13.python实现线索化二叉树

线索二叉树

二叉树的叶子节点会有一些空的指针,如果有n个节点则会有n+1个空指针域,将这些空指针域利用起来存在该二叉树为某一种遍历次序下的前驱节点和后继节点的二叉树成为线索二叉树。根据线索二叉树性质不同分为前序线索二叉树,中序线索二叉树,后续线索二叉树。

一个节点的前一个节点为前驱节点,一个节点的后一个节点为后继节点

核心思想
  • 当线索化二叉树的时候left和right就分为两种情况
    1. left指向左子树或者指向前驱节点
    2. right指向右子树或者后继节点
  • 实现线索化二叉树的需要对之前Node节点实体进行增强添加一个标记字段来记录left和right指针指向的是子树还是前驱或者后继节点
  • 在线索化二叉树的之后需要记录当前节点的上一个节点用于连接后继节点
  • 因为二叉树线索化之后left和right的定义已经改变所以遍历的方式也不同,用之前的方式遍历会出现死循环

class Node(object):
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None
        self.is_left_thread = False
        self.is_right_thread = False
        self.parent = None

    def add(self, node):
        if self.data > node.data:
            if self.left is None:
                self.left = node
                node.parent = self
            else:
                self.left.add(node)
        else:
            if self.right is None:
                self.right = node
                node.parent = self
            else:
                self.right.add(node)


class ThreadBinaryTree(object):

    def __init__(self):
        self.pre = None
        self.root = None

    def add(self, node):
        if self.root is None:
            self.root = node
        else:
            self.root.add(node)

    def post_order_thread(self, node):
        """
        后续线索化
        :return:
        """
        if node is None:
            return
        self.post_order_thread(node.left)
        self.post_order_thread(node.right)
        """
          1. left指向左子树或者指向前驱节点
          2. right指向右子树或者后继节点
        """
        if node.left is None:
            node.left = self.pre
            node.is_left_thread = True
        if self.pre is not None and self.pre.right is None:
            self.pre.right = node
            self.pre.is_right_thread = True; self.pre = node

    def post_order(self):
        """
        后续遍历
        :return:
        """
        temp = self.root
        # 定位到树最左端
        while temp.left is not None and temp.left.is_left_thread is False:
            temp = temp.left

        while temp is not None:
            # temp right 是后继节点
            if temp.is_right_thread:
                print(temp.data, end='->')
                self.pre = temp
                temp = temp.right
            else:
                # 后继节点之后的那一颗 子树需要特殊处理 必须拿到该子树的父节点然后继续
                if temp.right is self.pre:
                    print(temp.data, end='->')
                    self.pre = temp
                    temp = temp.parent
                else:
                    temp = temp.right
                    while temp.left is not None and temp.is_left_thread is False:
                        temp = temp.left


if __name__ == '__main__':
    binary_tree = ThreadBinaryTree()

    for i in range(1, 8):
        binary_tree.add(Node(i))

    binary_tree.post_order_thread(binary_tree.root)
    binary_tree.post_order()

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值