zoukankan      html  css  js  c++  java
  • 二叉查找树转变为有序双向链表

    题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。

      比如将二元查找树
                                             10
                                            /    
                                          6       14
                                        /       / 
                                     4     8  12   16
    转换成双向链表

    4=6=8=10=12=14=16。

    一道微软的面试题。

    二叉查找树的每个节点都有两个指针,双向链表的节点也是两个指针,不创建新节点只调整指针是可以完成转变的。

    对于二叉查找树的每个节点Node,它的左子树中所有的关键字都小于Node的关键字,而右子树中的所有关键字都大于Node的关键字。

    采用递归的思维可以很方便的完成转变,将节点的左右子树分别转变成有序链表,然后将节点的指针分别指向这两个链表。

    import random
    class Node(object):
        def __init__(self,key):
            self.key=key
            self.left=None
            self.right=None
    class BSTree(object):
        def __init__(self):
            self.root=None
        def put(self,key):
            if not self.root:
                self.root=Node(key)
            else:
                self.root=self._put(self.root,key)
        def _put(self,node,key):
            if node is None:
                node=Node(key)
            elif key<node.key:
                node.left=self._put(node.left,key)
            elif key>node.key:
                node.right=self._put(node.right,key)
            return node  
        def convert(self):
            if self.root:
                return self._convert(self.root)
        def _convert(self,node,asright=True):
            if not node:
                return None
            else:
                left=self._convert(node.left,False)
                if left:
                    left.right=node
                    node.left=left
                right=self._convert(node.right)
                if right:
                    right.left=node
                    node.right=right
                cur=node
                if asright:
                    while cur.left:
                        cur=cur.left
                if not asright:
                    while cur.right:
                        cur=cur.right
                return cur
                    
                
    if __name__=='__main__':
        t=BSTree()   
        for i in range(10):
            t.put(random.randint(0,100))    
        cur=t.convert()
        if cur:
            print cur.key
            while cur.right:
                cur=cur.right
                print cur.key
            while cur.left:
                cur=cur.left
                print cur.key

      另一种思路是采用中序遍历的方法。二叉查找树中序遍历的话就是从小到大排列。将遍历过的节点转为有序链表,然后将下一个要遍历的节点加到链表结尾。

    import random
    class Node(object):
        def __init__(self,key):
            self.key=key
            self.left=None
            self.right=None
    class Sorted_LinkedList(object):
        def __init__(self):
            self.head=None
        def travel(self):
            node=self.head
            while node:
                print node.key
                node=node.right
    class BSTree(object):
        def __init__(self):
            self.root=None
            self.list=Sorted_LinkedList()
            self.curNode=None
        def put(self,key):
            if not self.root:
                self.root=Node(key)
            else:
                self.root=self._put(self.root,key)
        def _put(self,node,key):
            if node is None:
                node=Node(key)
            elif key<node.key:
                node.left=self._put(node.left,key)
            elif key>node.key:
                node.right=self._put(node.right,key)
            return node  
        def convert(self):
            self._travel(self.root)
            return self.list
        def _travel(self,node):
            if node:
                 self._travel(node.left)
                 if self.curNode:
                     self.curNode.right=node
                     node.left=self.curNode
                 else:
                     self.list.head=node
                 self.curNode=node
                 self._travel(node.right)
                            
    if __name__=='__main__':
        t=BSTree()   
        for i in range(100):
            t.put(random.randint(0,100))
        l=t.convert()
        l.travel()
    

      

  • 相关阅读:
    D触发器的使用小结
    CAN通信帧ID的含义解析? (转载)
    mcp2515屏蔽寄存器和过滤寄存器的学习
    spi调试步骤,mcp2515调试整理
    最近工作小结2019.11.24
    Can总线上的电平及物理层仲裁
    can总线学习网上资料汇总
    can总线的远程帧(遥控帧)—说的很形象
    在IAR平台建立STC8ASK64S4A12单片机工程
    cortex-m系列的区别(图解)及今日碎片学习笔记
  • 原文地址:https://www.cnblogs.com/linxiyue/p/3753852.html
Copyright © 2011-2022 走看看