【算法】【python实现】二叉搜索树插入、删除、查找
二叉搜索树
定义:如果一颗二叉树的每个节点对应一个关键码值,且关键码值的组织是有顺序的,例如左子节点值小于父节点值,父节点值小于右子节点值,则这棵二叉树是一棵二叉搜索树。
类(TreeNode):定义二叉搜索树各个节点
在该类中,分别存放节点本身的值,以及其左子节点,右子节点,父节点的值。

class TreeNode(object):
def __init__(self,val):
self.value = val #存值
self.left = None #存本节点的左子节点
self.right = None #存本节点的右子节点
self.father = None #存本节点的父节点
类(BST):定义二叉搜索树的各种功能方法
此类用于存放定义二叉树的插入,删除,搜索等方法。
class BST(object):
def __init__(self,nodeList):
self.root = None
for node in nodeList:
self.bfs_insert(node)
注:self.bfs_insert(node)中的bfs_insert方法在后面实现。放在构造函数中的目的是将一个列表生成一个二叉搜索树列表。
方法(bfs_insert):实现插入功能
第一步:将根节点(self.root)设置成当前位置节点(cur),即从根节点开始遍历。根节点的父节点(father)初始设置为None。
def bfs_insert(self,node):
cur = self.root #设置当前节点为根节点
father = None #设置根节点的父节点为None
第二步:查找可以插入的位置
1. 当前位置节点(cur)的值与待插入节点(node)的值相等,返回-1(代表无法进行插入操作)。并将父节点(father)值修改为当前位置节点(cur),代表该节点已经遍历完成。
if cur.value == node.value:
return -1
father = cur
2.当前位置节点(cur)的值大于待插入节点(node)的值时,表示待插入节点(node)需继续在当前位置节点的左子树中继续查找。故把当前位置节点(cur)的左节点赋值给当前位置节点(cur),作为下一个要访问的节点对象。
if node.value < cur.value:
cur = cur.left


3.当前位置节点(cur)的值小于待插入节点(node)的值时,表示待插入节点(node)需继续在当前位置节点的右子树中继续查找。故把当前位置节点(cur)的右节点赋值给当前位置节点(cur),作为下一个要访问的节点对象。
if node.value > cur.value:
cur = cur.right


第三步:找到插入位置后,将其设置为待插入值(node)的父节点
node.father = father
第四步:插入操作
1.父节点的值为空(即要插入的是个空二叉树),将待插入节点(node)赋值给根节点(root)。
if father == None:
self.root = node
2.待插入节点(node)的值小于父节点(father)的值,将其放到父节点的左子节点
if node.value <father.value:
father.left = node
3.待插入节点(node)的值大于父节点(father)的值,将其放到父节点的右子节点
if node.value >father.value:
father.right = node

插入功能代码汇总:
def insert(self,node):
father = None
cur = self.root while cur != None:
if cur.value == node.value:
return -1
father = cur
if node.value < cur.value:
cur = cur.left
else:
cur = cur.right
node.father = father
if father == None:
self.root = node
elif node.value < father.value:
father.left = node
else:
father.right = node
方法(bfs):生成二叉搜索树列表
利用队列先进先出的特性,将一个二叉搜索树存放到列表中。
def bfs(self):
if self.root == None:
return None
retList = []
q = queue.Queue()
q.put(self.root)
while q.empty() is not True:
node = q.get()
retList.append(node.value)
if node.left != None:
q.put(node.left)
if node.right != None:
q.put(node.right)
return retList
示例:针对如下二叉搜索树,遍历存放到一个列表过程



ps:蓝色:二叉树列表 retList 橙色:队列 q
方法(bfs_search):实现查找功能
第一步:将根节点(self.root)设置成当前位置节点(cur),即从根节点开始遍历。
def search(self,value):
cur = self.root
如果cur值不为None,执行第二步。否则执行第三步
第二步:对比要查找的值(value)与当前位置节点(cur)的值的大小
1. 如果当前位置节点(cur)的值等于要查找的值(value),返回当前位置节点(cur)。
if cur.value == value:
return cur

2. 如果当前位置节点(cur)的值小于要查找的值(value),返回当前位置节点(cur)。
if cur.value < value:
cur = cur.right


3. 如果当前位置节点(cur)的值小于要查找的值(value),返回当前位置节点(cur)。
if cur.value > value:
cur = cur.left


第三步:如果cur的值为None,返回空。即查找的二叉搜索树为空树。
return None
查找功能代码汇总:
def search(self,value):
cur = self.root
while cur != None:
if cur.value == value:
return cur
elif cur.value < value:
cur = cur.right
else:
cur = cur.left
return None
方法(bfs_delete):实现删除功能
第一步:将待删除节点(node)的父节点赋值给father变量。
def delete(self,node):
father = node.father
第二步:判断待删除节点(node)的左子树是否为空
1. 待删除节点(node)的左子树为空
if node.left == None:
a) 待删除节点(node)为根节点
将待删除节点(node)的右子节点置为新的根节点(root),且其如果为非空,将其父节点(node.right.father)赋值为空。
if father == None:
self.root = node.right
if node.right != None:
node.right.father = None


b) 待删除节点(node)为其父节点的左子节点
待删除节点(node)的右子节点(node.right)取代其原来的位置,成为其父节点新的左子节点(father.left)。且其右子节点(node.right)不为空,将待删除节点(node)的父节点赋值给它的父节点(node.right.father)
if father.left == node:
father.left = node.right
if node.right != None:
node.right.father = father

c) 待删除节点(node)为其父节点的右子节点
待删除节点(node)的右子节点(node.right)取代其原来的位置,成为其父节点新的右子节点(father.right)。且其右子节点(node.right)不为空,将待删除节点(node)的父节点赋值给它的父节点(node.right.father)
if father.right == node:
father.right = node.right
if node.right != None:
node.right.father = father


2. 待删除节点(node)的左子树不为空
第一步:将待删除节点(node)的右子树挂到其左子树最后一层的右子节点下
a) 将待删除节点的左子节点(node.left)存到临时变量tmpNode中
tmpNode = node.left

b) 递归找到node.left的最后一层右子节点
while tmpNode.right != None:
tmpNode = tmpNode.right

c) 将待删节点的右子树(node.right)挂到node.left的最后一层右子节点下
tmpNode.right = node.right
d) 将node.right的父节点设置为待删节点左子树中的最后一层的右子节点
if node.right != None:
node.right.father = tmpNode
第二步:开始删除node
1.待删除节点为根节点
将待删除节点的左子节点(node.left)设置为根节点(self.root),并将其父节点设置为空。
if father == None:
self.root = node.left
node.left.father = None


2.待删除节点为根节点的左子节点
待删除节点的左子节点(node.left)取代待删节点的位置,并将其父节点设置为待删除节点的父节点。
if father.left == node:
father.left = node.left
node.left.father = father

3. 待删除节点为根节点的右子节点
待删除节点的左子节点(node.left)取代待删节点的位置,并将其父节点设置为待删除节点的父节点
if father.right == node:
father.right = node.left
node.left.father = father


删除功能代码汇总:
def delete(self,node):
father = node.father
if node.left == None:
if father == None:
self.root = node.right
if node.right != None:
node.right.father = None
elif father.left == node:
father.left = node.right
if node.right != None:
node.right.father = father
else:
father.right = node.right
if node.right != None:
node.right.father = father
return 'delete successfully'
tmpNode = node.left
while tmpNode.right != None:
tmpNode = tmpNode.right tmpNode.right = node.right
if node.right != None:
node.right.father = tmpNode if father == None:
self.root = node.left
node.left.father = None
elif father.left == node:
father.left = node.left
node.left.father = father
else:
father.right = node.left
node.left.father = father
node = None
return 'delete successfully'
综上,二叉搜索树代码
# encoding=utf-8
import queue class TreeNode(object):
def __init__(self,val):
self.value = val
self.left = None
self.right = None
self.father = None class BST(object):
def __init__(self,nodeList):
self.root = None
for node in nodeList:
self.bfs_insert(node) def bfs_insert(self,node):
father = None
cur = self.root while cur != None:
if cur.value == node.value:
return -1
father = cur
if node.value < cur.value:
cur = cur.left
else:
cur = cur.right
node.father = father
if father == None:
self.root = node
elif node.value < father.value:
father.left = node
else:
father.right = node def bfs(self):
if self.root == None:
return None
retList = []
q = queue.Queue()
q.put(self.root)
while q.empty() is not True:
node = q.get()
retList.append(node.value)
if node.left != None:
q.put(node.left)
if node.right != None:
q.put(node.right)
return retList def bfs_search(self,value):
cur = self.root
while cur != None:
if cur.value == value:
return cur
elif cur.value < value:
cur = cur.right
else:
cur = cur.left
return None def bfs_delete(self,node):
father = node.father
if node.left == None:
if father == None:
self.root = node.right
if node.right != None:
node.right.father = None
elif father.left == node:
father.left = node.right
if node.right != None:
node.right.father = father
else:
father.right = node.right
if node.right != None:
node.right.father = father
return 'delete successfully'
tmpNode = node.left
while tmpNode.right != None:
tmpNode = tmpNode.right tmpNode.right = node.right
if node.right != None:
node.right.father = tmpNode if father == None:
self.root = node.left
node.left.father = None
elif father.left == node:
father.left = node.left
node.left.father = father
else:
father.right = node.left
node.left.father = father
node = None
return 'delete successfully' if __name__ == '__main__':
varList = [24,34,5,4,8,23,45,35,28,6,29]
nodeList = [TreeNode(var) for var in varList]
bst = BST(nodeList)
print (bst.bfs())
node = bst.bfs_search(34)
bst.bfs_delete(node)
print (bst.bfs())
【算法】【python实现】二叉搜索树插入、删除、查找的更多相关文章
- Java与算法之(13) - 二叉搜索树
查找是指在一批记录中找出满足指定条件的某一记录的过程,例如在数组{ 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15 }中查找数字15,实现代码很简单 ...
- 看动画学算法之:平衡二叉搜索树AVL Tree
目录 简介 AVL的特性 AVL的构建 AVL的搜索 AVL的插入 AVL的删除 简介 平衡二叉搜索树是一种特殊的二叉搜索树.为什么会有平衡二叉搜索树呢? 考虑一下二叉搜索树的特殊情况,如果一个二叉搜 ...
- 在二叉搜索树(BST)中查找第K个大的结点之非递归实现
一个被广泛使用的面试题: 给定一个二叉搜索树,请找出其中的第K个大的结点. PS:我第一次在面试的时候被问到这个问题而且让我直接在白纸上写的时候,直接蒙圈了,因为没有刷题准备,所以就会有伤害.(面完的 ...
- 二叉搜索树(BST)的插入和删除递归实现
思路 二叉搜索树的插入 TreeNode InsertRec(rootNode, key) = if rootNode == NULL, return new Node(key) if key > ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- 二叉搜索树(BST)---python实现
github:代码实现 本文算法均使用python3实现 1. 二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜 ...
- LeetCode-450 二叉搜索树删除一个节点
二叉搜索树 建树 删除节点,三种情况,递归处理.左右子树都存在,两种方法,一种找到左子树最大节点,赋值后递归删除.找右子树最小同理 class Solution { public: TreeNode* ...
- 二叉搜索树(Binary Search Tree)--C语言描述(转)
图解二叉搜索树概念 二叉树呢,其实就是链表的一个二维形式,而二叉搜索树,就是一种特殊的二叉树,这种二叉树有个特点:对任意节点而言,左孩子(当然了,存在的话)的值总是小于本身,而右孩子(存在的话)的值总 ...
- 数据结构学习笔记_树(二叉搜索树,B-树,B+树,B*树)
一.查找二叉树(二叉搜索树BST) 1.查找二叉树的性质 1).所有非叶子结点至多拥有两个儿子(Left和Right): 2).所有结点存储一个关键字: 3).非叶子结点的左指针指向小于其关键字的子树 ...
随机推荐
- .net 信息采集ajax数据
.net 信息采集ajax数据 关于.net信息采集的资料很多,但是如果采集的网站是ajax异步加载数据的模式,又如何采集呢?今天就把自己做信息采集时,所遇到的一些问题和心得跟大家分享一下. 采集网站 ...
- VSCode 必装的 10 个高效开发插件
本文介绍了目前前端开发最受欢迎的开发工具 VSCode 必装的 10 个开发插件,用于大大提高软件开发的效率. VSCode 的基本使用可以参考我的原创视频教程「VSCode 高效开发必装插件」. V ...
- 基于C#的socket编程的TCP异步实现
一.摘要 本篇博文阐述基于TCP通信协议的异步实现. 二.实验平台 Visual Studio 2010 三.异步通信实现原理及常用方法 3.1 建立连接 在同步模式中,在服务器上使用Accept方法 ...
- JS 设计模式二 -- 单例模式
单例模式 概念 单例模式 就是保证一个类只有一个实例,并提供一个访问它的全局访问点. 实现方法 先判断实例是否存在,如果存在直接返回,如果不存在就创建实例后在返回,确保了一个类只有一个实例对象. va ...
- python关于二分查找
楔子 如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72 ...
- 其他综合-使用Xshell远程连接管理Linux实践
使用Xshell远程连接管理Linux实践 1. Xshell整体优化 1)点击 工具 ,然后选择 选项 2)在 常规 选项中,下面的存放路径根据个人爱好修改(可选默认) 3)在 更新 选项中,将 √ ...
- Nginx ACCESS阶段 Satisfy 指令
L:60 这里一定要记住 return 指令所对应的阶段 早与access 因此如果location 有return 的话 那么 deny可能都会失效
- [WC2018]通道——边分治+虚树+树形DP
题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...
- win+R启动列表
屌丝才用windows,无奈~ """ Win+R 快速启动的命令: 系统应用程序: calc - 启动计算器 charmap - 启动字符映射表 chkdsk - Ch ...
- RBAC权限管理设计
一.权限简介 1. 问:为什么程序需要权限控制? 答:生活中的权限限制,① 看灾难片电影<2012>中富人和权贵有权登上诺亚方舟,穷苦老百姓只有等着灾难的来临:② 屌丝们,有没有想过为什么 ...