数据结构与算法笔记(十六)—— 二叉搜索树
一、二叉搜索树定义
二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree)。
二叉搜索树是具有有以下性质的二叉树:
- 若左子树不为空,则左子树上所有节点的值均小于或等于它的根节点的值。
- 若右子树不为空,则右子树上所有节点的值均大于或等于它的根节点的值。
- 左、右子树也分别为二叉搜索树。
二、二叉搜索树的操作
2.1、结点创建
class Node(object):"""节点类"""def __init__(self, elem=-1, lchild=None, rchild=None,parent=None):self.elem = elemself.lchild = lchildself.rchild = rchildself.parent = parent
2.2、树的创建
class BTree(object):def __init__(self):self.root = Nonedef insert(self,node,val):'''为树添加结点: 递归'''if self.root is None:self.root = Node(val)returnif node is None:node = Node(val)return nodeif val < node.elem:node.lchild = self.insert(node.lchild,val)node.lchild.parent = nodeelif val > node.elem:node.rchild = self.insert(node.rchild,val)node.rchild.parent = nodereturn nodedef insert_no_rec(self,val):'''为树添加结点: 非递归'''p = self.rootif not p: #空树self.root = Node(val)returnwhile True:if val < p.elem:if p.lchild:p = p.lchildelse: #左孩子不存在p.lchild = Node(val)p.lchild.parent = preturnelif val > p.elem:if p.rchild:p = p.rchildelse: #右孩子不存在p.rchild = Node(val)p.rchild.parent = preturnelse:return
2.3、遍历
(即二叉树遍历,代码参考我博客:数据结构与算法笔记(十四)—— 二叉树)
2.4、查找
def search(self,val):p = self.rootwhile p:if p.elem <val:p = p.rchildelif p.elem > val:p = p.rchildelse:return Truereturn False
测试:
print(tree.search(20)) #结果:False
print(tree.search(13)) #结果:True
2.5、删除
二叉查找树的删除操作分为三种情况:
① 要删除的节点是叶子节点:直接删除
代码:
def delNode_1(self,node):'''情况1:node是叶子结点(即无左子树又无右子树)'''if not node.parent: #没有父节点说明是根节点self.root = Noneelif node == node.parent.lchild: #node是它父亲的左孩子node.parent.lchild = Noneelse: #node是它父亲的右孩子node.parent.rchild = None
② 要删除的节点只有一个孩子:将此节点的父亲与孩子连接,然后删除该节点
代码:
def delNode_21(self,node):'''情况2:node只有一个左孩子(只有左子树)'''if not node.parent: #没有父节点说明是根节点self.root = node.lchildelif node == node.parent.lchild: #node是它父亲的左孩子node.parent.lchild = node.lchildnode.lchild.parent = node.parentelse: #node是它父亲的右孩子node.parent.rchild = node.lchildnode.lchild.parent = node.parentdef delNode_22(self,node):'''情况2:node只有一个右孩子(只有右子树)'''if not node.parent: #没有父节点说明是根节点self.root = node.rchildelif node == node.parent.lchild: #node是它父亲的左孩子node.parent.lchild = node.rchildnode.rchild.parent = node.parentelse: #node是它父亲的右孩子node.parent.rchild = node.rchildnode.rchild.parent = node.parent
③ 要删节点既有左子树也有右子树:找到该节点右子树中最小值节点,使用该节点代替待删除节点,然后在右子树中删除最小值节点。
代码:
def defNode_3(self,node):'''情况3:既有左孩子又有右孩子'''min_node = node.rchildwhile min_node.lchild:min_node = min_node.lchildnode.data = min_node.elem# 删除min_nodeif min_node.rchild:self.delNode_22(min_node)else:self.delNode_1(min_node)
删除结点完整代码:
def delNode(self,val):'''删除二叉搜索树中值为val的点'''if not self.root:return False_,node = self.search(val)if not node:return Falseif not node.lchild and not node.rchild: #1.叶子结点self.delNode_1(node)elif not node.rchild: #2.1 只有一个左孩子self.delNode_21(node)elif not node.lchild: #2.3 只有一个右孩子self.delNode_22(node)else: #3.两个孩子都有self.defNode_3(node)
测试:
tree.preorder(tree.root) #结果:13 14 94 33 25 82 59 65
tree.delNode(13)
tree.preorder(tree.root) #结果:14 94 33 25 82 59 65
完整代码
class Node(object):"""节点类"""def __init__(self, elem=-1, lchild=None, rchild=None,parent=None):self.elem = elemself.lchild = lchildself.rchild = rchildself.parent = parentclass BTree(object):def __init__(self):self.root = Nonedef insert(self,node,val):'''为树添加结点: 递归'''if self.root is None:self.root = Node(val)returnif node is None:node = Node(val)return nodeif val < node.elem:node.lchild = self.insert(node.lchild,val)node.lchild.parent = nodeelif val > node.elem:node.rchild = self.insert(node.rchild,val)node.rchild.parent = nodereturn nodedef insert_no_rec(self,val):'''为树添加结点: 非递归'''p = self.rootif not p: #空树self.root = Node(val)returnwhile True:if val < p.elem:if p.lchild:p = p.lchildelse: #左孩子不存在p.lchild = Node(val)p.lchild.parent = preturnelif val > p.elem:if p.rchild:p = p.rchildelse: #右孩子不存在p.rchild = Node(val)p.rchild.parent = preturnelse:returndef search(self,val):p = self.rootwhile p:if p.elem <val:p = p.rchildelif p.elem > val:p = p.rchildelse:return True,preturn Falsedef preorder(self,node):'''先序遍历'''if node is None:returnprint(node.elem, end=' ')self.preorder(node.lchild)self.preorder(node.rchild)def delNode_1(self,node):'''情况1:node是叶子结点(即无左子树又无右子树)'''if not node.parent: #没有父节点说明是根节点self.root = Noneelif node == node.parent.lchild: #node是它父亲的左孩子node.parent.lchild = Noneelse: #node是它父亲的右孩子node.parent.rchild = Nonedef delNode_21(self,node):'''情况2:node只有一个左孩子(只有左子树)'''if not node.parent: #没有父节点说明是根节点self.root = node.lchildelif node == node.parent.lchild: #node是它父亲的左孩子node.parent.lchild = node.lchildnode.lchild.parent = node.parentelse: #node是它父亲的右孩子node.parent.rchild = node.lchildnode.lchild.parent = node.parentdef delNode_22(self,node):'''情况2:node只有一个右孩子(只有右子树)'''if not node.parent: #没有父节点说明是根节点self.root = node.rchildelif node == node.parent.lchild: #node是它父亲的左孩子node.parent.lchild = node.rchildnode.rchild.parent = node.parentelse: #node是它父亲的右孩子node.parent.rchild = node.rchildnode.rchild.parent = node.parentdef defNode_3(self,node):'''情况3:既有左孩子又有右孩子'''min_node = node.rchildwhile min_node.lchild:min_node = min_node.elemnode.data = min_node.elem# 删除min_nodeif min_node.rchild:self.delNode_22(min_node)else:self.delNode_1(min_node)def delNode(self,val):'''删除二叉搜索树中值为val的点'''if not self.root:return False_,node = self.search(val)if not node:return Falseif not node.lchild and not node.rchild: #1.叶子结点self.delNode_1(node)elif not node.rchild: #2.1 只有一个左孩子self.delNode_21(node)elif not node.lchild: #2.3 只有一个右孩子self.delNode_22(node)else: #3.两个孩子都有self.defNode_3(node)if __name__ == '__main__':li = [13,14,94,33,82,25,59,94,65]tree = BTree()
#=========添加结点============= for i in li:tree.insert(tree.root,i)tree.preorder(tree.root)print('')
#=========查找元素============= # print(tree.search(14))
#=========删除结点============= tree.delNode(13)print('')tree.preorder(tree.root)
数据结构与算法笔记(十六)—— 二叉搜索树相关推荐
- 数据结构--伸展树(伸展树构建二叉搜索树)-学习笔记
2019/7/16更新:封装SplayTree进入class:例题:http://poj.org/problem?id=3622 一个伸展树的板子: #include<stdio.h> # ...
- leetcode算法题--不同的二叉搜索树
原题链接:https://leetcode-cn.com/problems/unique-binary-search-trees/ 相关题目:leetcode算法题--不同的二叉搜索树 II 1.递归 ...
- 【数据结构笔记11】二叉搜索树,动态查找,删除操作
本次笔记内容: 4.1.1 二叉搜索树及查找 4.1.2 二叉搜索树的插入 4.1.3 二叉搜索树的删除 文章目录 动态查找 什么是二叉搜索树(BST) 二叉树的操作 二叉搜索树的查找操作 二叉搜索树 ...
- 数据结构与算法(3)——树(二叉、二叉搜索树)
前言:题图无关,现在开始来学习学习树相关的知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 数据结构与算法(2)-- ...
- 算法导论笔记:12二叉搜索树
1:概念 二叉搜索树也叫二叉排序树,它支持的操作有:SEARCH, MINIMUM, MAXIMUM, PREDECESSOR, SUCCESSOR, INSERT, DELETE.所以,一颗二叉搜索 ...
- 《恋上数据结构第1季》平衡二叉搜索树、AVL树
AVL树 二叉搜索树缺点分析 改进二叉搜索树 平衡(Balance) 理想平衡 如何改进二叉搜索树? 平衡二叉搜索树(Balanced Binary Search Tree) AVL树 BST 对比 ...
- 算法:最优二叉搜索树
算法设计第五次作业part2 1.纸面题:对最优二叉树和矩阵连乘两种算法验证四边形法则,如果符合四边形法则则举几个正例,如果不符合则举几个反例 四边形法则 i<i'j<j'w(i,j)+w ...
- 算法实验 最优二叉搜索树
最优二叉搜索树 最优二叉搜索树 问题描述 问题分析 代码 问题描述 二叉搜索树我们都知道,左子树结点的值都小于根结点,右子树结点的值都大于根节点.如果某个结点没有左子树或右子树,那么在对应的位置上加一 ...
- 数据结构与算法笔记 —— 十大经典排序及算法的稳定性
一.十大经典排序算法 排序算法是<数据结构与算法>中最基本的算法之一. 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全 ...
- 数据结构和算法三十六
剑指 Offer 66. 构建乘积数组 题目:给定一个数组 A[0,1,-,n-1],请构建一个数组 B[0,1,-,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B ...
最新文章
- R包操作相关:安装、卸载、加载、移除、已经安装的包、包的路径、函数查看等
- 全国大学生智能汽车竞赛介绍-2020
- bond、服务器登录、跟踪数据包的路由
- Angular全套知识讲解,错过必悔!
- java中四种默认的权限修饰符,Java中四种访问权限资料整理
- Java SE 8新功能导览:Java开发世界中的重大变化
- oracle u01目录 100,文件目录空间利用率达到100%而导致数据库异常挂起的故障处理过...
- RTSP之主流安防厂家地址
- caffe/build/tools下会生成一些工具
- [HihoCoder1369]网络流一·Ford-Fulkerson算法
- 计算机组成原理讲义 微盘,计算机组成原理课件.pdf
- 无线网卡wifi破解
- premiere学习笔记01帧定格,时间码,透明视频,调整图层,转场及批量转场,插件安装,音频调整,关键帧,马赛克,蒙版,嵌套序列
- 学习笔记:FW内容安全概述
- 推荐一个Spring Cloud Alibaba 的代码生成器项目
- 基金指数温度怎么算_10分钟学会计算指数温度,挑选指数基金
- 34%的人会出轨。。。
- Xshell连接不上?
- [BZOJ1233][Usaco2009Open]干草堆tower(单调队列优化)
- 利用Python做一个漂亮小姐姐词云跳舞视频
热门文章
- easyloging 获取日志文件名字_愉快地学Java语言:第十五章 断言与日志
- Leetcode 200 岛屿数量 (每日一题 20210720)
- 子数组的最大累加和问题
- 错误处理:IndexError: index out of range in self
- pyecharts 应用4: 二维散点图
- Tableau 2020.3 发布!新增 写入外部数据库 与 预测建模 等功能,进一步增强扩展分析
- Linux中date命令用法及大小比较
- mysql通用查询日志_MySQL通用查询日志(GeneralQueryLog)_MySQL
- LeetCode-链表-24. 两两交换链表中的节点
- Matlab中typecast函数由int8转换为int32