笔记
python实现二叉搜索树
# -*- coding: UTF-8 -*-
'''
*****************LLL*********************
* @Project :leetcode
* @File :lll_110二叉搜索树.py
* @IDE :PyCharm
* @Author :LLL
* @Date :2022/6/3 17:41
*****************************************
'''
from random import shuffle
# binary search tree
class BST:
# 树节点
class TreeNode:
def __init__(self, val, lchild=None, rchild=None, parent=None):
self.val = val
self.lchild = lchild
self.rchild = rchild
self.parent = parent
# 初始化根节点为空
def __init__(self, li):
self.root = None
if li:
for val in li:
self.insert_no_rec(val)
# 插入(递归写法) 从根节点开始,查找适合插入的位置
def insert(self, root, val):
if not root:
root = self.TreeNode(val)
elif val < root.val:
root.lchild = self.insert(root.lchild, val)
root.lchild.parent = root
elif val > root.val:
root.rchild = self.insert(root.rchild, val)
root.rchild.parent = root
else:
pass
return root
# 插入(非递归写法)
def insert_no_rec(self, val):
tmp_node = self.root
# 如果没有根节点
if not tmp_node:
self.root = self.TreeNode(val)
return
while tmp_node:
if val < tmp_node.val:
if not tmp_node.lchild: # 为None说明已经到了叶子结点
tmp_node.lchild = self.TreeNode(val)
tmp_node.lchild.parent = tmp_node
return
tmp_node = tmp_node.lchild
elif val > tmp_node.val:
if not tmp_node.rchild:
tmp_node.rchild = self.TreeNode(val)
tmp_node.rchild.parent = tmp_node
return
tmp_node = tmp_node.rchild
else:
return
# 查询(递归写法)
def query(self, root, val):
if not root: return # 如果没有根 返回None
if val < root.val: # 小于 就在左子树上查找
return self.query(root.lchild, val)
if val > root.val: # 大于 就在右子树上查找
return self.query(root.rchild, val)
else: # 等于就直接返回当前节点
return root
# 查询(非递归写法)
def query_no_rec(self, val):
tmp_node = self.root
if not tmp_node: return
while tmp_node:
if val < tmp_node.val: # 小于就查找左子树
tmp_node = tmp_node.lchild
elif val > tmp_node.val: # 大于就查找右子树
tmp_node = tmp_node.rchild
else:
return tmp_node
# 删除
def delete(self, val):
# 三种情况
'''
1.如果要删除的节点是叶子结点,直接删除
2.如果要删除的节点只有一个孩子(不管是左孩子还是右孩子),将其孩子连向其父亲,然后删除该节点
3.如果要删除的节点有两个孩子,寻找左子树的最大节点(或者右子树的最小节点)替换当前节点
'''
tmp_node = self.query_no_rec(val)
if tmp_node:
# 情况1
if not tmp_node.lchild and not tmp_node.rchild: # 如果是叶子节点
if tmp_node.parent:
if tmp_node.parent.lchild == tmp_node:
tmp_node.parent.lchild = None
else:
tmp_node.parent.rchild = None
else: # 如果是根节点
self.root = None
# 情况2
elif tmp_node.lchild:
tmp_node.parent.lchild = tmp_node.lchild
tmp_node.lchild.parent = tmp_node.parent
elif tmp_node.rchild:
tmp_node.parent.rchild = tmp_node.rchild
tmp_node.rchild.parent = tmp_node.parent
# 情况3
else:
tmp_node2 = tmp_node.rchild # 右子树
while tmp_node2.lchild: # 寻找右子树值最小的节点
tmp_node2 = tmp_node2.lchild
tmp_node3 = tmp_node2.parent
while tmp_node3.rchild:
tmp_node3 = tmp_node3.rchild
tmp_node.val = tmp_node2.val
tmp_node2.parent.lchild = None
tmp_node3.rchild = tmp_node2.rchild
tmp_node2.rchild.parent = tmp_node3
else:
print('要删除的节点不存在!')
# 前序遍历
def pre_order(self, root):
if root:
print(root.val, end=' ')
self.in_order(root.lchild)
self.in_order(root.rchild)
# 中序遍历
def in_order(self, root):
if root:
self.in_order(root.lchild)
print(root.val, end=' ')
self.in_order(root.rchild)
# 后序遍历
def post_order(self, root):
if root:
self.post_order(root.lchild)
self.post_order(root.rchild)
print(root.val, end=' ')
if __name__ == '__main__':
li = list(range(1, 20))
shuffle(li)
bst = BST(li)
print()
# bst.pre_order(bst.root)
print()
bst.in_order(bst.root)
bst.delete(1)
# bst.delete(2)
# bst.delete(16)
# bst.delete(19)
print()
bst.in_order(bst.root)
同步更新于个人博客系统:python实现二叉搜索树