一、二叉搜索树定义

二叉搜索树(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)

数据结构与算法笔记(十六)—— 二叉搜索树相关推荐

  1. 数据结构--伸展树(伸展树构建二叉搜索树)-学习笔记

    2019/7/16更新:封装SplayTree进入class:例题:http://poj.org/problem?id=3622 一个伸展树的板子: #include<stdio.h> # ...

  2. leetcode算法题--不同的二叉搜索树

    原题链接:https://leetcode-cn.com/problems/unique-binary-search-trees/ 相关题目:leetcode算法题--不同的二叉搜索树 II 1.递归 ...

  3. 【数据结构笔记11】二叉搜索树,动态查找,删除操作

    本次笔记内容: 4.1.1 二叉搜索树及查找 4.1.2 二叉搜索树的插入 4.1.3 二叉搜索树的删除 文章目录 动态查找 什么是二叉搜索树(BST) 二叉树的操作 二叉搜索树的查找操作 二叉搜索树 ...

  4. 数据结构与算法(3)——树(二叉、二叉搜索树)

    前言:题图无关,现在开始来学习学习树相关的知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 数据结构与算法(2)-- ...

  5. 算法导论笔记:12二叉搜索树

    1:概念 二叉搜索树也叫二叉排序树,它支持的操作有:SEARCH, MINIMUM, MAXIMUM, PREDECESSOR, SUCCESSOR, INSERT, DELETE.所以,一颗二叉搜索 ...

  6. 《恋上数据结构第1季》平衡二叉搜索树、AVL树

    AVL树 二叉搜索树缺点分析 改进二叉搜索树 平衡(Balance) 理想平衡 如何改进二叉搜索树? 平衡二叉搜索树(Balanced Binary Search Tree) AVL树 BST 对比 ...

  7. 算法:最优二叉搜索树

    算法设计第五次作业part2 1.纸面题:对最优二叉树和矩阵连乘两种算法验证四边形法则,如果符合四边形法则则举几个正例,如果不符合则举几个反例 四边形法则 i<i'j<j'w(i,j)+w ...

  8. 算法实验 最优二叉搜索树

    最优二叉搜索树 最优二叉搜索树 问题描述 问题分析 代码 问题描述 二叉搜索树我们都知道,左子树结点的值都小于根结点,右子树结点的值都大于根节点.如果某个结点没有左子树或右子树,那么在对应的位置上加一 ...

  9. 数据结构与算法笔记 —— 十大经典排序及算法的稳定性

    一.十大经典排序算法 排序算法是<数据结构与算法>中最基本的算法之一. 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全 ...

  10. 数据结构和算法三十六

    剑指 Offer 66. 构建乘积数组 题目:给定一个数组 A[0,1,-,n-1],请构建一个数组 B[0,1,-,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B ...

最新文章

  1. R包操作相关:安装、卸载、加载、移除、已经安装的包、包的路径、函数查看等
  2. 全国大学生智能汽车竞赛介绍-2020
  3. bond、服务器登录、跟踪数据包的路由
  4. Angular全套知识讲解,错过必悔!
  5. java中四种默认的权限修饰符,Java中四种访问权限资料整理
  6. Java SE 8新功能导览:Java开发世界中的重大变化
  7. oracle u01目录 100,文件目录空间利用率达到100%而导致数据库异常挂起的故障处理过...
  8. RTSP之主流安防厂家地址
  9. caffe/build/tools下会生成一些工具
  10. [HihoCoder1369]网络流一·Ford-Fulkerson算法
  11. 计算机组成原理讲义 微盘,计算机组成原理课件.pdf
  12. 无线网卡wifi破解
  13. premiere学习笔记01帧定格,时间码,透明视频,调整图层,转场及批量转场,插件安装,音频调整,关键帧,马赛克,蒙版,嵌套序列
  14. 学习笔记:FW内容安全概述
  15. 推荐一个Spring Cloud Alibaba 的代码生成器项目
  16. 基金指数温度怎么算_10分钟学会计算指数温度,挑选指数基金
  17. 34%的人会出轨。。。
  18. Xshell连接不上?
  19. [BZOJ1233][Usaco2009Open]干草堆tower(单调队列优化)
  20. 利用Python做一个漂亮小姐姐词云跳舞视频

热门文章

  1. easyloging 获取日志文件名字_愉快地学Java语言:第十五章 断言与日志
  2. Leetcode 200 岛屿数量 (每日一题 20210720)
  3. 子数组的最大累加和问题
  4. 错误处理:IndexError: index out of range in self
  5. pyecharts 应用4: 二维散点图
  6. Tableau 2020.3 发布!新增 写入外部数据库 与 预测建模 等功能,进一步增强扩展分析
  7. Linux中date命令用法及大小比较
  8. mysql通用查询日志_MySQL通用查询日志(GeneralQueryLog)_MySQL
  9. LeetCode-链表-24. 两两交换链表中的节点
  10. Matlab中typecast函数由int8转换为int32