剑指offer - 二叉搜索树和双向链表 - python

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树

题目描述:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

思路:

二叉搜索树可分为根节点、左子树和右子树,在把左、右子树转换成排序的双向链表后再和根节点链接起来,整棵搜索二叉树就转换成了排序的双向链表。因此这个过程可以分为两个阶段:

  • 将左、右子树转换为双向排序链表
  • 将左、右子树的转换链表和其对应的根节点链接

整个过程通过可以递归进行。


在这里插入图片描述

  • 中序遍历法:从上图转换后得到得双向链表可以看出,链表中元素得排列就是二叉树中序遍历后得结果。因此,当得到中序遍历后的结果,我们只需要做的是从第一个节点( i = 1 i = 1 )开始,将第 i + 1 i + 1 个结点作为第 i i 个结点的left,将第i个结点作为第 i + 1 i+1 个结点的right,不断操作直到最后 i i 。是不是很巧妙呢?所以说,在题目操作可视化后可以更直观的观察最后的结果,根据数据结构的特性就可能想到更简便的方法。

剑指offer 二叉搜索树与双向链表 python


AC代码

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, pRootOfTree):
        def find_right(node):
            while node.right:
                node = node.right
            return node
        # write code here
        if pRootOfTree == None:
            return None
        
		# 左、右子树
        leftNode = self.Convert(pRootOfTree.left)
        rightNode = self.Convert(pRootOfTree.right)
		
        # 记录最终输出链表的头结点,只为输出
        retNode = leftNode
		
        # 处理左子树
        if leftNode:
            # 找到左子树的双向链表的最后一个结点
            leftNode = find_right(leftNode)
        else:
            retNode = pRootOfTree
		
        # 将根节点指向左子树链表的最后一个结点和右子树链表的第一个结点
        pRootOfTree.left = leftNode
        pRootOfTree.right = rightNode
		
        # 另一个方向的链接,将左子树链表的最后一个节点指向根节点,将右子树链表的第一个节点指向根节点
        if leftNode != None:
            leftNode.right = pRootOfTree
        if rightNode != None:
            rightNode.left = pRootOfTree

        return retNode

中序遍历法

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, pRootOfTree):
        if not pRootOfTree:
            return
        self.mid = []
        self.middle(pRootOfTree)
        for i in range(len(self.mid)-1):
            self.mid[i].right = self.mid[i+1]
            self.mid[i+1].left = self.mid[i]

        return self.mid[0]

    def middle(self, root):
        if not root:
            return
        self.middle(root.left)
        self.mid.append(root)
        self.middle(root.right)

发布了295 篇原创文章 · 获赞 103 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/Forlogen/article/details/104883747