3.6python如何把二叉树转换为双向链表

题目描述:

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,要求不能创建任何新的结点,只能调整结点的指向。例如:
在这里插入图片描述

思路:
由于转换后的双向链表中的结点的顺序与二叉树的中序遍历的顺序相同,所以可以对二叉树的中序遍历算法进行修改,通过在中序遍历的过程中修改结点的指向来转换成一个排序的双向链表。实现思路如下图所示:
假设当前遍历的结点为 root,root的左子树已经被转换为双向链表(如下图(1)所示),使用两个变量 pHead 与 pEnd 分别指向链表的首结点与尾结点。那么在遍历 root 结点的时候,只需要将 root 结点的 lchild (左) 指向 pEnd,把 pEnd 的 rchild (右) 指向 root;此时 root 结点就被加入到双向链表里了,所以 root 变成了双向链表的尾结点。对于所有的结点都可以通过同样的方法来修改结点的指向。所以可以采用递归的方法来求解。在求解的时候需要特别注意递归的结束条件以及边界情况(l例如双向链表为空的时候)。
在这里插入图片描述

算法性能分析:
此方法与二叉树的中序遍历有着相同的时间复杂度O(n);
此外,这种方法只用了两个额外的变量 pHead 与 pEnd 来记录双向链表的首尾结点,所以空间复杂度为O(1);

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2020/1/24 10:38
# @Author  : buu
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/weixin_44321080
class BiTNode:
    def __init__(self):
        self.data = None
        self.lchild = None
        self.rchild = None


class Test:
    def __init__(self):
        self.pHead = None  # 双向链表首结点
        self.pEnd = None  # 双向链表尾结点

    def array2treee(self, arr, start, end):
        """
        把有序数组转换为二叉树
        :param arr:数组
        :param start:数组起点
        :param end:数组终点
        :return:
        """
        root = None
        if end >= start:
            root = BiTNode()
            mid = (start + end + 1) // 2
            root.data = arr[mid]  # 树的根节点为数组中间的元素
            # print(root.data,end=' ')
            root.lchild = self.array2treee(arr, start, mid - 1)  # 递归地构建左子树
            root.rchild = self.array2treee(arr, mid + 1, end)  # 递归地构建右子树
        else:
            root = None
        return root

    def inOrderBSTree(self, root):
        """
        把二叉树转换为双向链表,中序遍历,左,根,右
        :param root: 树的根结点
        :return:
        """
        if root == None:
            return
        self.inOrderBSTree(root.lchild)  # 转换root的左子树
        root.lchild = self.pEnd  # 使当前结点的左孩子指向双向链表的最后一个结点
        if self.pEnd == None:  # 若双向链表为空,则当前遍历的结点为双向链表的头结点
            self.pHead = root
        else:
            self.pEnd.rchild = root  # 使双向链表中最后一个结点的右孩子指向当前结点
        self.pEnd = root  # 将当前结点设为双向链表中最后一个结点
        self.inOrderBSTree(root.rchild)  # 转换root的右子树


if __name__ == '__main__':
    arr = [1, 2, 3, 4, 5, 6, 7]
    test = Test()
    root = test.array2treee(arr, 0, len(arr) - 1)
    test.inOrderBSTree(root)
    print('双向链表的正向遍历: ',end='')
    cur=test.pHead
    while cur != None:
        print(cur.data,end=' ')
        cur=cur.rchild
    print()
    print('双向链表的逆向遍历: ',end='')
    cur=test.pEnd
    while cur != None:
        print(cur.data,end=' ')
        cur=cur.lchild


结果:
在这里插入图片描述
end

发布了76 篇原创文章 · 获赞 2 · 访问量 2557

猜你喜欢

转载自blog.csdn.net/weixin_44321080/article/details/104078230
今日推荐