剑指 Offer 36. 二叉搜索树与双向链表

150 阅读1分钟

参考链接

问题简述

  1. 将二叉树转换成中序遍历线索二叉树
  2. 将其首尾连接,变成循环链表

问题分析

  1. 对于二叉树的操作,基于遍历
  2. 线索二叉树:利用了空指针域,将其指向遍历序列的前驱与后继
  3. 遍历方法分为两类:递归、非递归
  4. 在遍历的基础上,维护两个指针:遍历序列中的前驱、当前节点

代码

主要介绍:中序非递归的写法,以及两种解题方法(递归、非递归)

中序(前序)非递归

  1. 优先(循环)使用stack压入cur.left
  2. cur指向None, 检查stack中是否为空,pop出栈顶给cur
  3. 调整一次cur指向cur.right
代码如下:
class Solution:
    def inOrderNonRecursive(self, root: 'Node'):
        if not root: return None
        stack = []
        showRes = []
        cur = root
        while(cur or stack):
            while(cur):
                showRes.append(cur)  # 前序,记得注释掉此行
                stack.append(cur)
                cur = cur.left
            if stack: 
                cur = stack.pop()
                showRes.append(cur)  # 中序 
            cur = cur.right
        return showRes

转为线索二叉树

对于cur来说,precur在遍历中的前驱

if pre: 
    pre.right = cur 
    cur.left = pre
else: 
    head = cur

中序非递归解法

class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        if not root: return None
        stack = []
        pre, head = None, None
        cur = root
        while(cur or stack):
            while(cur):
                stack.append(cur)
                cur = cur.left
            if stack:
                cur = stack.pop()
                if pre: 
                    pre.right = cur
                    cur.left = pre
                else: 
                    head = cur
            pre = cur
            cur = cur.right

        head.left = pre
        pre.right = head
        return head

中序递归解法

class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        if not root: return None
        def dfs(cur):
            if not cur: return
            if cur.left: dfs(cur.left)

            if self.pre:
                self.pre.right, cur.left = cur, self.pre
            else:
                self.head = cur

            self.pre = cur
            if cur.right: dfs(cur.right)

        self.pre = None
        self.head = None
        dfs(root)
        self.head.left = self.pre
        self.pre.right = self.head
        return self.head