数据结构之二叉查找树介绍

目录

一、定义

二、二叉查找树的搜索

三、二叉查找树的插入

四、二叉查找树的删除

五、总结


一、定义

二叉查找树(Binary Search Tree),也叫二叉搜索树或二叉排序树,它或者是一棵空树。

二叉查找树具有下列性质:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树

下图就是一个标准的二叉查找树:

可见,从根节点50开始,左子树的所有节点的值都比根节点50小,右子树的所有节点的值都比根节点大。

二、二叉查找树的搜索

根据上面提到的二叉查找树的特性,当搜索一个节点在树中的位置时,我们需要从根节点出发:

  • (1)如果查找的元素对应的值比当前节点对应的值小,则到它的左子树去进行查找;
  • (2)如果查找的元素对应的值比当前节点对应的值大,则到它的右子树去进行查找;
  • (3)如果查找的元素对应的值等于当前节点对应的值,说明找到了;
  • (4)如果直至叶子节点都找不到对应的值,说明该元素不存在该树中;

以上面的二叉查找树为例,如果我们要搜索45节点在树中的位置,大体流程如下:

  • 【a】从根节点50出发,45 < 50,小于50,则去50的左子树进行查找,当前节点变为30;
  • 【b】比较45 > 30,大于30,则去30的右子树进行查找,当前节点变为40;
  • 【c】比较45 > 40,大于40,则会40的右子树进行查找,当前节点变为45;
  • 【d】比较45 = 45,刚好相等,找到目标节点,整个查找过程结束;

如下图所示:

三、二叉查找树的插入

二叉查找树进行插入的话,首先必须找出需要插入的位置,这个搜索过程跟上面的流程一样,找到插入位置后直接插入即可,大体包括下面的步骤:

  • 如果当前二叉查找树是一颗空树,则直接创建节点进行插入即可;
  • 如果当前二叉查找树不是空树,则有下面三个情况:
  • 如果插入节点的值比当前节点的值小,则到它的左子树去插入,依次递归查找,如果左子树或者节点为空,则插入到这个位置;
  • 如果插入节点的值比当前节点的值大,则到它的右子树去插入,依次递归查找,如果右子树或者节点为空,则插入到这个位置;
  • 如果插入节点的值与当前节点的值相等,说明该元素已经在树中存在了,直接返回;

下面以一个示例说明二叉查找树的插入过程:依次插入元素【10、21、30、15、25、35、40、5】,下面是具体的构建过程:

总体原则:根据左小右大找到插入位置进行插入。

【a】插入10

【b】插入20

【c】插入30

【d】插入15

【e】插入25

【f】插入35

【g】插入40

【h】插入5

可见,构建过程比较简单,就是挨个进行比较,比当前节点值小就去左子树去插入,比当前节点值大就去右子树去插入。

四、二叉查找树的删除

删除节点也会涉及到查找删除的节点位置这一步,同样跟上面的查找流程类似。删除前首先要找到该节点,如果找不到,说明树中不存在此节点,不进行任何操作,直接结束即可。

 二叉查找树删除大致可以分为以下三种情况:

  • 删除节点是叶子节点,无子节点,直接删除即可;
  • 待删除的节点只有一个子节点,那么用该子节点接到删除节点的父节点即可;
  • 待删除的节点有两个子节点,那么使用前或后继节点作为替换节点,对删除节点进行数据替换,然后转移至删除替换节点即可;

【a】删除节点是叶子节点,无子节点

 如果删除节点35,因为35是叶子节点,所以直接删除即可。

【b】待删除的节点只有一个子节点,那么用该子节点接到删除节点的父节点即可

如果我们删除节点35,因为35只有一个子节点32,所以只需要将32连接到40的左子树上面,断开35和40的连接即可,如下图:

【c】待删除的节点有两个子节点,那么使用前或后继节点作为替换节点,对删除节点进行数据替换,然后转移至删除替换节点即可

在二叉搜索树中,寻找前后继节点很简单:

  • 前继节点:小于当前节点的,在左子树中最右边的那个节点。
  • 后继节点:大于当前节点的,在右子树中最左边的那个节点。

查找过程:

  • (1)寻找前继节点,当前节点左子树进行查找,然后右转一直走到底(右子节点为null时终止);
  • (2)寻找后继节点,当前节点右子树中查找,然后左转一直走到底(左子节点为null时终止);

如下图所示:

下面我们需要删除节点10,具体删除流程如下图所示:

注意:上图中的15应该是10的后继节点,笔者笔误了。

五、总结

本文主要总结了二叉搜索树的一些特性,以及二叉搜索树的查找流程、插入、删除流程,并通过示例讲解了具体是怎么操作的,但是二叉搜索树在极端情况下的查询效率不是很高,复杂度可能会是O(n),如下图:

 

造成上面的原因主要是树不平衡,为了解决这种不平衡,推出了平衡二叉搜索树,平衡二叉搜索树(AVL树、红黑树等)就是为了解决这个问题:

平衡二叉树在进行插入、删除后,会进行自平衡,从而保证其查询的时间复杂度接近于O(log2n)。

小伙伴们可以在下面的网址进行动态构建二叉搜索树、红黑树等等,可以加深二叉搜索树的插入、删除等流程。

https://www.cs.usfca.edu/~galles/visualization/BST.html

已标记关键词 清除标记
1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。2.网上数据结构和算法的课程不少,但存在两个问题:1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级 3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。教程内容:本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二、二与数组转换、二排序(BST)、AVL、线索二、赫夫曼、赫夫曼编码、多路查找(BB+和B*)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。学习目标:通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值