二叉查找树

二叉查找树(Binary Search Tree),也称二叉搜索树、有序二叉树(ordered binary tree),排序二叉树(orted binary tree),是指一棵空树或者具有下列性质的二叉树:

  • 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
  • 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
  • 任意节点的左、右子树也分别为二叉查找树;
  • 没有键值相等的节点

二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,均为O(log n)。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、multiset、关联数组等。

常用操作

定义树的节点如下:

class Node:def __init__(self, val):self.val = valself.left = Noneself.right = None

1. 查找

在二叉搜索树 b b b中查找x" role="presentation" style="position: relative;">xxx的过程为:

  1. 若b是空树,则搜索失败,否则:
  2. 若x等于b的根节点的数据域之值,则查找成功;否则:
  3. 若x小于b的根节点的数据域之值,则递归搜索左子树;否则:
  4. 递归查找右子树

使用python实现如下:

def search(root, val):if root == None:return False, Noneelif val > root.val:return search(root.right, val)elif val < root.val:return search(root.left, val)else:return True, root

2. 插入

向一个二叉搜索树 b b b中插入一个节点s" role="presentation" style="position: relative;">sss的算法,过程为:

  • 若b是空树,则将s所指结点作为根节点插入,否则:
  • 若s.val等于b的根节点的数据域之值,则返回,否则:
  • 若s.val小于b的根节点的数据域之值,则把s所指节点插入到左子树中,否则:
  • 把s所指节点插入到右子树中(新插入节点总是叶子节点)
def insert(self, root, node):"""insert inplace"""if root ==  None:root = nodereturnif node.val == root.val:returnelif node.val > root.val:self.insert(root.right, node)else:self.insert(root.left, node)

3. 删除

二叉搜索树的删除操作分三种情况讨论:
1. 如果待删除的节点是叶子节点,那么可以立即被删除,如下图所示:
例:删除数据为16的节点,是叶子节点,可以直接删除

2. 如果有一个子节点,要将下一个子节点上移到当前节点,即替换之
例:删除数据为25的节点,它下面有唯一一个子节点35, 上移到替换之

3. 如果有两个子节点,则将其右子树的最小数据代替此节点的数据,并将其右子树的最小数据删除,如下图所示
例:删除节点数据为5的节点,找到被删除节点右子树的最小节点。需要一个临时变量successor,将11节点下面的子节点进行查询,找到右子树最小节点7,并把右子树最小节点7替换被删除节点,维持二叉树结构。如下图

class solution:def deleteNode(self, root, key):""":type root: TreeNode:type key: int:rtype: TreeNode"""if root == None:return Noneif key < root.val:root.left = self.deleteNode(root.left, key)elif key > root.val:root.right = self.deleteNode(root.right, key)else:if root.left == None:return root.rightelif root.right == None:return root.leftelse:min_node = self.findMinNode(root.right)root.val = min_node.valroot.right = self.deleteNode(root.right, root.val)return rootdef findMinNode(self, node):while node.left:node = node.leftreturn node

4. 遍历

可以采用前序,中序,后序来遍历该二叉搜索树,或者使用广度优先搜索的方式。这里用中序遍历来实现,可以保证按从小到大的顺序打印。

def traverse_binary_tree(root):if root is None:returntraverse_binary_tree(root.left)print(root.value)traverse_binary_tree(root.right)

5. 构造一颗二叉查找树

用一组数值建造一棵二叉查找树的同时,也把这组数值进行了排序。其最差时间复杂度为 O(n2) O ( n 2 ) {\displaystyle O(n^{2})}。例如,若该组数值经是有序的(从小到大),则建造出来的二叉查找树的所有节点,都没有左子树

def build_binary_tree(values):tree = Nonefor v in values:tree = insert(tree, Node(v))return tree

性能分析

查找:最佳情况 Olog(n) O l o g ( n ) Olog(n), 最坏情况 O(n) O ( n ) O(n)
插入:最佳情况 Olog(n) O l o g ( n ) Olog(n), 最坏情况 O(n) O ( n ) O(n)
删除:最佳情况 Olog(n) O l o g ( n ) Olog(n), 最坏情况 O(n) O ( n ) O(n)

二叉查找树(BST)的基本概念及常用操作相关推荐

  1. arcgis坐标系未定义_科学网—ArcGIS中的坐标系:基本概念和常用操作 - 李郎平的博文...

    ArcGIS中的坐标系:基本概念和常用操作 李郎平,Email: lilp@lreis.ac.cn 中国科学院地理科学与资源研究所,资源与环境信息系统国家重点实验室 缘由:介绍GIS(地理信息系统)中 ...

  2. pod概念及常用操作

    pod概念及常用操作 pod概念:什么是pod init容器(初始化容器) pause容器(Infra容器) 修改默认infro容器 普通pod: pod资源限制: pod生命周期介绍 Pending ...

  3. MongoDB基本概念和常用操作(一)

    基本操作 MongoDB将数据存储为一个文档,数据结构由键值(key=>value)对组成 MongoDB文档类似于JSON对象,字段值可以包含其他文档.数组.文档数组 安装管理mongodb环 ...

  4. MongoDB基本概念和常用操作(二)

    数据查询 基本查询 方法find():查询 db.集合名称.find({条件文档}) 方法findOne():查询,只返回第一个 db.集合名称.findOne({条件文档}) 方法pretty(): ...

  5. 二叉查找树BST的删除操作

    二叉查找树BST的删除操作(哈工大版) C++代码 /***** 二叉查找树BST *****/ #include<iostream> using namespace std;struct ...

  6. docker 删除所有未启动的容器_Docker 镜像容器常用操作(让我们用 docker 溜得飞起)...

    推荐阅读: 面试字节跳动三轮凉凉,内推4面终拿下抖音offer(Java后台研发)​zhuanlan.zhihu.com 一线架构师Spring boot 学习笔记:我的成长全记在这份PDF文档里​z ...

  7. 超全整理|Python 操作 Excel 库 xlwings 常用操作详解!

    在之前的文章中我们曾详细的讲解了如何使用openpyxl 操作Excel,其实在Python中还有其他可以直接操作 Excel 文件的库,如 xlwings.xlrd.xlwt 等等,本文就将讲解另一 ...

  8. Kubernetes与Docker基本概念与常用命令对照

    摘要: Docker是众多用户上手入门的基础容器和编排工具,提供了良好的开发者体验.Kubernetes是强大的容器编排平台,功能丰富.它们有很多概念和操作都有类似之处.我们今天会和大家对比基本概念与 ...

  9. 【数据库】第一章 数据库的分类、SQL、数据库、表和表记录的常用操作

    [数据库]第一章 数据库的分类.SQL.数据库与表的常用操作 文章目录 [数据库]第一章 数据库的分类.SQL.数据库与表的常用操作 一.数据库的分类 1.关系型数据库 2.非关系型数据库 3.MyS ...

最新文章

  1. 一起学设计模式 - 责任链模式
  2. TLS实现代码段加密
  3. oracle指定源位置怎么弄,ORACLE Goldengate测试解决源端和目标端表结构字段位置不同的2种实现方法...
  4. Chapter 4 Invitations——25
  5. 横向对比5大开源语音识别工具包,CMU Sphinx最佳
  6. breakall lisp文件_CAD导入草图大师后自动成面
  7. pycharm专业版账号登录问题
  8. 必备的查询网址:查征信、婚姻、交友借钱明明白白
  9. 【流媒体开发】9、ffmpeg实现视频录制
  10. 微信双开,手机如何开启微信分身?
  11. php发送文本邮件和带附件邮件
  12. egret与php相连,JavaScript_Mac OS X 系统下安装和部署Egret引擎开发环境, 概述 Egret基于TypeScript开 - phpStudy...
  13. 安装程序向硬盘复制文件是遇到错误:[Errno 5] Input/out error ;U盘安装Ubuntu18.04.1遇到错误
  14. c语言既是素数又是回文数的三位数,编写程序,找出所有既是素数又是回文数的三位正整数.例如:131等...
  15. 高级网络管理员必学知识
  16. 百度智能云人脸识别java_demo完整实例
  17. 使用 deeplabv3+ 训练自己的数据集经验总结
  18. NGINX的奇淫技巧 —— 5. NGINX实现金盾防火墙的功能(防CC)
  19. PyQt如何使界面按钮更加美观
  20. 【Pyecharts50例】添加自定义地图/geojson使用/区县地图

热门文章

  1. Mask Scoring Rcnn论文解读《Mask Scoring R-CNN》
  2. C语言学习笔记(十五)
  3. java变量_Java变量
  4. 粉色噪声 褐色噪声 布朗噪声
  5. 如何查询一个IP上所绑定的域名
  6. C语言中_exit()、exit()、return区别
  7. RBF-UKF径向基神经网络结合无迹卡尔曼滤波估计锂离子电池SOC(附MATLAB代码)
  8. c语言课程设计图像处理,摄影与图像处理课程设计
  9. 解决kali无法定位软件包
  10. 小程的第一节C语言课