python二叉树删除节点_二叉查找树的增加,删除,遍历 python

本文介绍了如何使用Python实现二叉查找树(包括插入、删除和查找节点的方法)。通过创建一个值为8的根节点,逐步演示了插入1、3、6、4、7、10、14、13等节点的过程,详细解释了每个插入步骤。此外,还讨论了删除节点的三种情况:无子节点、一个子节点和两个子节点,并提供了相应的删除操作示例。
摘要由CSDN通过智能技术生成

让我们来创建一个值为8的根结点,这个时候,左右节点均是None

root =Node(8)

如下图看到的,我们创建了一个只有一个节点的树

309e6450a812f273f9e7dfe7c70f1dea.png

我们需要一个方法来插入元素让我们的单个节点的树变的充实起来,这个方法的参数是个数值和某个节点本身(根节点/二叉查找树)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

class Node : . . . def insert ( self , data ) : """ Insert new node with data @param data node data object to insert """ if self . data : if data < self . data : if self . left is None : self . left = Node ( data ) else : self . left . insert ( data ) elif data > self . data : if self . right is None : self . right = Node ( data ) else : self . right . insert ( data ) else : self . data = data

插入方法会递归的调用,直到为我们的元素(节点)找到合适的位置

.

让我们来增加3个元素(节点),然后看看我们的插入方法是如何运行的

1

root.insert(3)

2

root.insert(10)

3

root.insert(1)

插入元素3(节点)的过程:

第一步: 根结点调用插入方法,调用时传入的变量为3

第二步:3比8小,而且 根节点8的左节点为None,所以我们直接把3这个节点(3的左右节点均为None),放到8的左节点上

插入元素10(节点)的过程:

根节点调用insert方法,传入变量10

10大于根节点,并且根节点的右分支为None,所以我们把10放到根节点的右分支

插入元素1(节点)的过程:

根节点调用insert方法,传入参数1

1比8小,并且8这个根结点有左侧分值(不为None),所以,根结点的左节点调用insert方法,传入参数1

这个时候,1比3小,并且3没有左分支,我们就把1放到了3的左节点上

现在的结构是:

6256d669bcd98dd69c93cdf7fd157281.png

让我们继续插入新的元素让树更加充实.

1

root.insert(6)

2

root.insert(4)

3

root.insert(7)

4

root.insert(14)

5

root.insert(13)

插入完成后的栗子:

285fd2a037239d5c3b3077ec4b6e6fcd.png

我们需要一个方法能够帮助我们找到具体的某一个节点,这个方法会接收一个数值,返回这个数值所在的节点,并返回它的父节点(如果不寸再就返回None)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

class Node : . . . def lookup ( self , data , parent = None ) : """ Lookup node containing data @param data node data object to look up @param parent node's parent @returns node and node's parent if found or None, None """ if data < self . data : if self . left is None : return None , None return self . left . lookup ( data , self ) elif data > self . data : if self . right is None : return None , None return self . right . lookup ( data , self ) else : return self , parent

我们试着查找下6

1

node, parent =root.lookup(6)

具体的查找过程:

第一步: 传入参数6,默认的parent = None

第二步:6 小于根节点的8

第三步:这个时候,根结点的左节点3,继续调用lookup函数,这个时候的parent就是当前的节点了

第四步:6比3大

第五步:然后3的右节点(孩子),调用lookup

第六步:发现6等于3的右孩子,找到了!

867c7003dde9dfe39749750b9b189dc2.png

删除方法需要传入的参数就是一个节点的值

1 2 3 4 5 6 7 8 9 10 11 12 13

class Node : . . . def delete ( self , data ) : """ Delete node containing data @param data node's content to delete """ # get node containing data node , parent = self . lookup ( data ) if node is not None : children_count = node . children_count ( ) . . .

删除的时候有三种情况:

1:被删除的节点没有子节点

2:被删除的节点有一个子节点.

3:被删除的节点有2个子节点

第一种情况是非常简单的,我只需要将这个节点删除,然后将它的父节点相应的子节点置为None即可

1 2 3 4 5 6 7 8 9 10 11 12 13

def delete ( self , data ) : . . . if children_count == 0 : # if node has no children, just remove it if parent : if parent . left is node : parent . left = None else : parent . right = None del node else : self . data = None . . .

注:方法children_count()会返回一个节点的子节点的个数

children_count:

1 2 3 4 5 6 7 8 9 10 11 12 13 14

class Node : . . . def children_count ( self ) : "" " Returns the number of children @returns number of children: 0, 1, 2 " "" cnt = 0 if self . left : cnt += 1 if self . right : cnt += 1 return cnt

举个例子,我们想删除节点1,3的左分支会被设置成None

1

root.delete(1)

c76fe63b4302763a0613e4dcf4f18682.png

让我们来看一下第二种情况,这个时候,我们需要用它的子节点来代替被删除的节点

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

def delete ( self , data ) : . . . elif children_count == 1 : # if node has 1 child # replace node with its child if node . left : n = node . left else : n = node . right if parent : if parent . left is node : parent . left = n else : parent . right = n del node else : self . left = n . left self . right = n . right self . data = n . data . . .

举个例子,我们想删除节点14,这个时候,13会代替14,然后新的13的左右分支会被置为None

1

root.delete(14)

bc5f0f4247253719aa19f227805b6b9d.png

让我们来看一下最后一种可能,就是被删除节点有两个子节点,我们会用其中一个来代被删除的节点,并递归的完成这个过程

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

def delete ( self , data ) : . . . else : # if node has 2 children # find its successor parent = node successor = node . right while successor . left : parent = successor successor = successor . left # replace node data by its successor data node . data = successor . data # fix successor's parent's child if parent . left == successor : parent . left = successor . right else : parent . right = successor . right

举例子:我们想要删除3,这个时候我们会递归的去查找右测元素,终于找到4,我们将4替换3,然后将6的子节点值None

1

root.delete(3)

f5011159d621cc8bd202a40ad51896e4.png

参考地址: http://www.laurentluce.com/posts/binary-search-tree-library-in-python/comment-page-1/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值