python 双向链表_python-025-把二叉树转换为双向链表

题目:给定一个二叉树,将其转换为双向链表。

双向链表的特征是每一个节点都保存着其前驱节点和后继节点的地址,而二叉树是一样的结构,只不过是左右孩子的节点的地址,所以我们只需要将左孩子节点指针作为前驱节点指针,右孩子节点指针作为后继节点指针即可。

非常明显我们又要利用递归了,这题还有其他解法,这里就不多说了。

双向链表有两个头节点,一个Phead,一个Pend,如何在转换二叉树时如何保存这个双向链表的前后头结点,是一个难题,可以写一个双向链表对象,其属性为self.phead,和self.pend,然后将转变二叉树作为它的一个方法。

当然也可以用函数式编程,将这两个指针在函数内声明为全局变量即可。

具体思路,用中序遍历算法改编,(很多对二叉树的算法都是用三种遍历方式改编来的)

遍历每一个节点时,改变其指针指向:

pend.right_child = root

root.left_child = pend

pend = root

上面的过程即可使节点加入到双向链表的尾部。

代码实现:

def BiTreeToDLink(root):

global pHead

global pEnd

if root is None:

return

#左子树

BiTreeToDLink(root.left_child)

#根节点的左孩子指向pEnd,pEnd的有孩子指向root

root.left_child=pEnd

if None == pEnd:

pHead=root

else:

pEnd.right_child = root

#右子树

pEnd=root

BiTreeToDLink(root.right_child)

运行:

if __name__ == '__main__':

root=constuctBiTree(12)

print("中序遍历:")

print_tree_mid_order(root)

pHead=None

pEnd=None

BiTreeToDLink(root)

cur=pHead

print("双向链表正序:")

while cur is not None:

print(cur.data)

cur=cur.right_child

cur = pEnd

print("双向链表倒序:")

while cur is not None:

print(cur.data)

cur = cur.left_child

运行结果,我链表用的随机数组生成的:

5686e8c9810d?from=timeline

image.png

5686e8c9810d?from=timeline

image.png

5686e8c9810d?from=timeline

image.png

明白了吗?

全部代码:

import random

class BiTNode:

"""docstring for BiTNode"""

def __init__(self,arg):

self.data = arg

self.left_child = None

self.right_child = None

def arrayToBiTree(array):

#判断arr是否为空

if len(array)==0:

return BiTNode(array[0])

mid=len(array)//2 # 有序数组的中间元素的下标

#print(mid)

#start=0 # 数组第一个元素的下标

#end=-1 # 数组最后一个元素的下标

if len(array)>0:

#将中间元素作为二叉树的根

root=BiTNode(array[mid])

#如果左边的元素个数不为零,则递归调用函数,生成左子树

if len(array[:mid])>0:

root.left_child = arrayToBiTree(array[:mid])

#如果右边的元素个数不为零,则递归调用函数,生成左子树

if len(array[mid+1:])>0:

root.right_child = arrayToBiTree(array[mid+1:])

return root

def constuctBiTree(x):

#构造一个没有零的二叉树

arr=[]

for i in range(x):

x=random.randint(0,9)

arr.append(x)

print(arr)

root=arrayToBiTree(arr)

return root

#中序遍历

def print_tree_mid_order(root):

#先判断二叉树是否为空,当左右节点都为空时

if root is None:

return

#中序遍历 左根右

#遍历左子树

if root.left_child is not None:

print_tree_mid_order(root.left_child)

#遍历根节点

print(root.data)

#遍历右子树

if root.right_child is not None:

print_tree_mid_order(root.right_child)

def BiTreeToDLink(root):

global pHead

global pEnd

if root is None:

return

#左子树

BiTreeToDLink(root.left_child)

#根节点的左孩子指向pEnd,pEnd的有孩子指向root

root.left_child=pEnd

if None == pEnd:

pHead=root

else:

pEnd.right_child = root

#右子树

pEnd=root

BiTreeToDLink(root.right_child)

if __name__ == '__main__':

root=constuctBiTree(12)

print("中序遍历:")

print_tree_mid_order(root)

pHead=None

pEnd=None

BiTreeToDLink(root)

cur=pHead

print("双向链表正序:")

while cur is not None:

print(cur.data)

cur=cur.right_child

cur = pEnd

print("双向链表倒序:")

while cur is not None:

print(cur.data)

cur = cur.left_child

今天的就到这里,我想我以后应该早上发文。

今天尝试ajax爬取,分析ajax给我弄懵了。。。。

一会继续试一试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值