我的编程空间,编程开发者的网络收藏夹
学习永远不晚

何为二叉搜索树

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

何为二叉搜索树

本篇内容主要讲解“何为二叉搜索树”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“何为二叉搜索树”吧!

什么是树

树是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

 何为二叉搜索树

树是递归的,将树的任何一个节点以及节点下的节点都能组合成一个新的树,所以树的很多问题都是使用递归去完成。

根节点: 最上面的那个节点(root),根节点没有父节点,只有子节点(0个或多个都可以)

层数: 一般认为根节点是第1层(有的也说第0层),而树的高度就是层数最高(上图层数开始为1)节点的层数

节点关系:

  • 父节点:连接该节点的上一层节点,

  • 孩子节点: 和父节点对应,上下关系。而祖先节点是父节点的父节点(或者祖先)节点。

  • 兄弟节点:拥有同一个父节点的节点们!

节点的度: 就是节点拥有孩子节点的个数(是直接连接的孩子不是子孙).

树的度: 就是所有节点中最大 (节点的度)。同时,如果度大于0的节点是分支节点,度等于0的节点是叶子节点(没有子孙)。

相关性质:

何为二叉搜索树

二叉树

二叉树是一树的一种,但应用比较多,所以需要深入学习,二叉树的每个节点最多只有两个子节点(但不一定非得要有两个节点)。

二叉树与度为2的树的区别:

1、度为2的的树必须有三个节点以上(否则就不叫度为二了,一定要先存在),二叉树可以为空。

2、二叉树的度不一定为2,比如斜树

3、二叉树有左右节点区分,而度为2的树没有左右节点的区分。

几种特殊二叉树:

满二叉树:高度为n的满二叉树有(2^n) -1个节点

何为二叉搜索树

满二叉树

完全二叉树:上面一层全部满,最下一层从左到右顺序排列

何为二叉搜索树

完全二叉树

二叉排序树:树按照一定规则插入排序(本文详解)。

平衡二叉树:树上任意节点左子树和右子树深度差距不超过1(后文详解).

二叉树性质:

1、二叉树有用树的性质

2、非空二叉树叶子节点数=度为2的节点数+1.本来一个节点如果度为1.那么一直延续就一个叶子,但如果出现一个度为2除了延续原来的一个节点,会多出一个节点需要维系。所以到最后会多出一个叶子。

3、非空第i层最多有2^(i-1)个节点。

4、高为h的树最多有(2^h)-1个节点(等比求和)。

二叉树一般用链式存储,这样内存利用更高,但二叉树也可以用数组存储的(经常会遇到),各个节点对应的下标是可以计算出来的,就拿一个完全二叉树若从左往右,从上到下编号如图:

何为二叉搜索树

二叉树节点位置对应关系

二叉排序(搜索)树

概念

前面铺垫那么多,咱们言归正传,详细讲解并实现一个二叉排序树,二叉搜索树拥有二叉树的性质,同时有一些自己的规则:

首先要了解二叉排序树的规则:从任意节点开始,节点左侧节点值总比节点右侧值要小

例如一个二叉排序树依次插入15,6,23,7,4,71,5,50会形成下图顺序

 何为二叉搜索树

一个二叉排序树

构造

二叉排序树是由若干节点(node)构成的,对于node需要这些属性:left,right,和value。其中left和right是左右指针指向左右孩子子树,而value是储存的数据,这里用int  类型。

node类构造为:

class node {//结点     public int value;     public node left;     public node right;     public node()     {     }     public node(int value)     {         this.value=value;         this.left=null;         this.right=null;     }     public node(int value,node l,node r)     {         this.value=value;         this.left=l;         this.right=r;     }            }

既然节点构造好了,那么就需要节点等其他信息构造成树,有了链表构造经验,很容易得知一棵树最主要的还是root根节点。

所以树的构造为:

public class BinarySortTree {     node root;//根     public BinarySortTree()     {root=null;}     public void makeEmpty()//变空     {root=null;}     public boolean isEmpty()//查看是否为空     {return root==null;}     //各种方法 }

可以用图来表示一下这个结构:

 何为二叉搜索树

主要方法

既然已经构造好一棵树,那么就需要实现主要的方法,因为二叉排序树中每个节点都能看作一棵树。所以我们创建方法的是时候加上节点参数(方便一些递归调用)

findmax(),findmin()

findmin()找到最小节点:

因为所有节点的最小都是往左插入,所以只需要找到最左侧的返回即可,具体实现可使用递归也可非递归while循环。

findmax()找到最大节点:

因为所有节点大的都是往右面插入,所以只需要找到最右侧的返回即可,实现方法与findmin()方法一致。

代码使用递归函数

public node findmin(node t)//查找最小返回值是node,调用查看结果时需要.value {     if(t==null) {return null;}     else if(t.left==null) {return t;}     else return(findmin(t.left));    } public node findmax(node t)//查找最大 {     if(t==null) {return null;}     else if(t.right==null) {return t;}     else return(findmax(t.right));   }

一个图中查找最大最小过程如下:

 何为二叉搜索树

查找过程

isContains(int x)

这里的意思是查找二叉查找树中是否存在值为x的节点。

在具体实现上,根据二叉排序树左侧更小,右侧更大的性质进行往下查找,如果找到值为x的节点则返回true,如果找不到就返回false,当然实现上可以采用递归或者非递归,我这里使用非递归的方式。

public boolean isContains(int x)//是否存在 {     node current=root;     if(root==null) {return false;}     while(current.value!=x&&current!=null)      {         if(x<current.value) {current=current.left;}         if(x>current.value) {current=current.right;}         if(current==null) {return false;}//在里面判断如果超直接返回     }     //如果在这个位置判断是否为空会导致current.value不存在报错      if(current.value==x) {return true;}             return false;        }

insert(int x)

插入的思想和前面isContains(int x)类似,找到自己的位置(空位置)插入。

但是具体实现上有需要注意的地方,我们要到待插入位置上一层节点,你可能会疑问为什么不直接找到最后一个空,然后将current赋值过去current=new  node(x),这样的化current就相当于指向一个new  node(x)节点,和原来树就脱离关系(原树相当于没有任何操作),所以要提前通过父节点判定是否为空找到位置,找到合适位置通过父节点的left或者right节点指向新创建的节点才能完成插入的操作。

public node insert(int x)// 插入 t是root的引用 {     node current = root;     if (root == null) {         root = new node(x);         return root;     }     while (current != null) {         if (x < current.value) {             if (current.left == null) {                 return current.left = new node(x);}             else current = current.left;}         else if (x > current.value) {             if (current.right == null) {                 return current.right = new node(x);}             else current = current.right;         }     }     return current;//其中用不到 }

比如说上面树插入值为51的节点。

何为二叉搜索树

插入值为51的节点

delete(int x)

删除操作算是一个相对较难理解的操作了,因为待删除的点可能在不同位置所以具体处理的方式也不同,如果是叶子即可可直接删除,有一个孩子节点用子节点替换即可,有两个子节点的就要先找到值距离待删除节点最近的点(左子树最大点或者右子树最小点),将值替换掉然后递归操作在子树中删除已经替换的节点,当然没具体分析可以看下面:

删除的节点没有子孙:

这种情况不需要考虑,直接删除即可(节点=null即可)(图中红色点均满足这种方式)。

何为二叉搜索树

待删除节点为叶子节点

一个子节点为空:

此种情况也很容易,直接将删除点的子节点放到被删除位置即可。

 何为二叉搜索树

待删除节点有1个孩子

左右节点均不空

左右孩子节点都不为空这种情况是相对比较复杂的,因为不能直接用其中一个孩子节点替代当前节点(放不下,如果孩子节点也有两个孩子那么有一个节点无法放,例如拿下面71节点替代)

 何为二叉搜索树

待删除节点有两个孩子

如果拿19或者71节点填补。虽然可以保证部分侧大于小于该节点,但是会引起合并的混乱.比如你若用71替代23节点。那么你需要考虑三个节点(19,50,75)之间如何处理,还要考虑他们是否满,是否有子女,这是个复杂的过程,不适合考虑。

所以,我们要分析我们要的这个点的属性:能够保证该点在这个位置仍满足二叉搜索树的性质(找到值最近的),那么子树中哪个节点满足这样的关系呢?

左子树中最右侧节点或者右子树中最左侧节点都满足,我们可以选一个节点将待删除节点值替换掉(这里替换成左子树最右侧节点)。

这个点替换之后该怎么办呢?很简单啊,二叉树用递归思路解决问题,再次调用删除函数在左子树中删除替换的节点即可。

 何为二叉搜索树

先替换值再递归在子树中删除18节点

这里演示是选取左子树最大节点(最右侧)替代,当然使用右子树最小节点也能满足在这待删除的大小关系,原理一致。整个删除算法流程为:

何为二叉搜索树

删除流程

这部分操作的代码为:

public node remove(int x, node t)// 删除节点 {   if (t == null) {     return null;   }   if (x < t.value) {     t.left = remove(x, t.left);   } else if (x > t.value) {     t.right = remove(x, t.right);   } else if (t.left != null && t.right != null)// 左右节点均不空   {     t.value = findmin(t.right).value;// 找到右侧最小值替代     t.right = remove(t.value, t.right);   } else // 左右单空或者左右都空   {     if (t.left == null && t.right == null) {       t = null;     } else if (t.right != null) {       t = t.right;     } else if (t.left != null) {       t = t.left;     }     return t;   }   return t; }

完整代码

这个完整代码是笔者在大三时候写的,可能有不少疏漏或者不规范的地方,仅供学习参考,如有疏漏错误还请指正。

二叉排序树完整代码为:

何为二叉搜索树

何为二叉搜索树

何为二叉搜索树

何为二叉搜索树

到此,相信大家对“何为二叉搜索树”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

何为二叉搜索树

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

2023-09-01

二叉搜索树(C++)

二叉搜索树 概念二叉搜索树的应用二叉搜索树的实现K模型基本结构和函数声明接口实现①find——查找关键码②Insert——插入关键码③Erase——删除关键码(==重点==)时间复杂度 源码(整体)非递归递归
2023-08-30

Python实现二叉搜索树

二叉搜索树我们已经知道了在一个集合中获取键值对的两种不同的方法。回忆一下这些集合是如何实现ADT(抽象数据类型)MAP的。我们讨论两种ADT MAP的实现方式,基于列表的二分查找和哈希表。在这一节中,我们将要学习二叉搜索树,这是另一种键指向
2022-06-04

Java中如何把二叉搜索树转换为累加树

这篇文章主要介绍了Java中如何把二叉搜索树转换为累加树,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、题目给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加
2023-06-25

C++二叉搜索树BSTree如何使用

这篇文章主要介绍“C++二叉搜索树BSTree如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++二叉搜索树BSTree如何使用”文章能帮助大家解决问题。一、概念二叉搜索树又称二叉排序树,它
2023-07-05

C++二叉搜索树实例分析

本篇内容介绍了“C++二叉搜索树实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!独一无二的二叉搜索树Given an integer
2023-06-19

C++如何实现验证二叉搜索树

本文小编为大家详细介绍“C++如何实现验证二叉搜索树”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++如何实现验证二叉搜索树”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。验证二叉搜索树Example 1:In
2023-06-19

如何在Java中操作二叉搜索树

如何在Java中操作二叉搜索树?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、二叉搜索树插入元素 class Node { int val;
2023-06-15

C++二叉搜索树BSTree使用详解

二叉搜索树(BinarySearchTree)又称二叉排序树,也称作二叉查找树它或者是一棵空树,或者是具有以下性质的二叉树,若它的左子树不为空,则左子树上所有节点的值都小于根节点的值,若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
2023-03-09

C++实现验证二叉搜索树代码

本篇内容主要讲解“C++实现验证二叉搜索树代码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++实现验证二叉搜索树代码”吧!验证二叉搜索树Given a binary tree, determ
2023-06-20

java二叉搜索树使用实例分析

本篇内容主要讲解“java二叉搜索树使用实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java二叉搜索树使用实例分析”吧!概念二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性
2023-06-29

C++LeetCode0538二叉搜索树转换累加树示例

这篇文章主要为大家介绍了C++LeetCode0538二叉搜索树转换累加树示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-16

C++怎么把二叉搜索树转换累加树

今天小编给大家分享一下C++怎么把二叉搜索树转换累加树的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。把二叉搜索树转换为累加树
2023-07-04

编程热搜

目录