什么是二叉搜索树
二叉搜索树(BST,Binary Search Tree), 也称二叉排序树或二叉查找树 。一棵二叉树,可以为空;如果不为空,满足以下性质:

  1. 非空左子树的所有键值小于其根结点的键值(/关键字)。
  2. 非空右子树的所有键值大于其根结点的键值
  3. 左、右子树都是二叉搜索树
  • 注意:二叉排序树中没有相同关键字的结点。对二叉搜索树进行中序遍历可以得到按关键字排序的有序序列。*
//在讨论二叉排序树上的运算之前,定义其节点的类型如下:
typedef int keyType
typedef struct node         //记录类型
{ KeyType key;              //关键字项
InfoType data;             //其他数据域
struct node *lchild,*rchild;   //左右孩子指针
}
BSTNode;

二叉搜索树的指定结点的查找
顾名思义,这种二叉树就是用来查找的。
因为二叉排序树可看做是一个有序表,所以在二叉排序树上进行查找,和二分查找类似,也是一个逐步缩小查找范围的过程。
查找从根结点开始,如果树为空,返回NULL 。
若搜索树非空,则根结点关键字和X进行比较,并进行不同处理:
若X小于根结点键值,只需在左子树中继续搜索;如果X大于根结点的键值,在右子树中进行继续搜索; 若两者比较结果是相等,搜索完成,返回指向此结点的指针。

//递归
BSTNode *SearchBST(BSTNode *bt,KeyType k)
{  if(bt==NULL || bt->key==k)         //递归终结条件
return bt;
if (k<bt->key)
return SearchBST(bt->lchild,k); //在左子树中递归查找
else return SearchBST(bt->rchild,k); //在右子树中递归查找
}

由于非递归函数的执行效率高,可将“尾递归”函数改为迭代函数

//非递归
BSTNode *SearchBST1(BSTNode *bt,KeyType k)
{
while (bt!=NULL)
{if (k==bt->key)return bt;
else if (k<bt->key)bt=bt->lchild;  //在左子树中递归查找
elsebt=bt->rchild;  //在左子树中递归查找
}
return NULL;     //没有找到返回NULL
}

注:查找的效率决定于树的高度

查找最大和最小元素
按照性质,最大元素一定是在树的最右分枝的端结点上 ;最小元素一定是在树的最左分枝的端结点上 。参考代码如下,按英文意思进行理解即可:

//查找最小元素的递归函数
Position FindMin( BinTree BST )
{
if( !BST )
return NULL; /*空的二叉搜索树,返回NULL*/
else if( !BST->Left ) return BST;  /*找到最左叶结点并返回*/
else  return FindMin( BST->Left ); /*沿左分支继续查找*/ } //查找最大元素的迭代函数
Position FindMax( BinTree BST )
{
if(BST)
while( BST->Right )
BST = BST->Right;         /*沿右分支继续查找,直到最右叶结点*/
return BST;
}    

二叉搜索树的插入
关键是要找到元素应该插入的位置。
插入过程:
(1)若二叉排序树T为空,则创建一个key域为k的节点,将它作为根节点;
(2)否则将k和根节点的关键字比较,若两者相等,则说明树中已有此关键字k,无须插入,直接返回0;
(3)若kkey,则将k插入根节点的左子树中。
(4)否则将它插入右子树

int InsertBST(BSTNode *&p,KeyType k)     //在以*p为根节点的BST中插入一个关键字为k的节点。插入成功返回1,否则返回0
{
if(p==NULL)             //原树为空, 新插入的记录为根节点
{
p=(BSTNode*)malloc(sizeof(BSTNode));
p->key=k;
p->lchild=p->rchild=NULL;
return 1;
}
else if  (k==p->key)               //存在相同关键字的节点,返回0
return 0;
else if (k<p->key) return InsertBST(p->lchild,k); //插入到左子树中
else  return InsertBST(p->rchild,k);             //插入到右子树中}

二叉搜索树的生成
二叉排序树的生成,是从一个空树开始,每插入一个关键字,就调用一次插入算法将它插入到当前已生成的二叉排序树中。

BSTNode *CreatBST(KeyType A[],int n) //返回树根指针
{
BSTNode *bt=NULL;    //初始时bt为空树
int i=0;
while (i<n)
{
InsertBST(bt,A[i]);  //将A[i]插入二叉排序树T中
i++;
}
return bt;         //返回建立的二叉排序树的根指针}

任何节点插入到二叉排序树时,都是以叶子节点插入的。

**二叉搜索树的删除 **
这个过程是最复杂的。
1.①被删除的节点是叶子节点:直接删去该节点。其双亲节点中相应指针域的值改为“空”
②被删除的节点只有左子树或者只有右子树,用其左子树或者右子树代替它。其双亲节点的相应指针域的值改为 “指向被删除节点的左子树或右子树”。
③被删除的节点既有左子树,也有右子树:以其前驱替代之,然后再删除该前驱节点。前驱是左子树中最大的节点

int DeleteBST(BSTNode *&bt,KeyType k)          //在bt中删除关键字为k的节点
{
if(bt==NULL) return 0;   //空树删除失败
else
{if (k<bt->key)
return DeleteBST(bt->lchild,k);//递归在左子树中删除为k的节点
else if (k>bt->key) return DeleteBST(bt->rchild,k);//递归在右子树中删除为k的节点
else
{
Delete(bt);    //调用Delete(bt)函数删除*bt节点
return 1;
}
}}void Delete(BSTNode *&p)    //从二叉排序树中删除*p节点
{
BSTNode *q;
if(p->rchild==NULL)      //*p节点没有右子树的情况
{
q=p;
p=p->lchild;   //其左子树的根节点放在被删节点的位置上
free(q);
}
else if (p->lchild==NULL)    //*p节点没有左子树
{
q=p;
p=p->rchild;                //其右子树的根节点放在被删节点的位置
free(q);
}
else Delete1(p,p->lchild);    //*p节点既有左子树又有右子树的情况
}void Delete1(BSTNode *p,BSTNode *&r) //当被删*p节点有左右子树时的删除过程
{
BSTNode *q;
if (r->rchild!=NULL) Delete1(p,r->rchild);      //递归找最右下节点
else     //找到了最右下节点*r
{
p->key=r->key;            //将*r的关键字值赋给*p
q=r;
r=r->lchild;                   //将左子树的根节点放在被删节点的位置上
free(q); //释放原*r的空间
}}

2.另一种类似做法:
考虑三种情况: 
①要删除的是叶结点:直接删除,并再修改其父结点指针—置为NULL ;

②要删除的结点只有一个孩子结点: 将其父结点的指针指向要删除结点的孩子结点 ;

③要删除的结点有左、右两棵子树: 用另一结点替代被删除结点:右子树的最小元素 或者 左子树的最大元素 ;取右子树中的最小元素替代 ,取左子树中的最大元素替代 ;

BinTree Delete( ElementType X, BinTree BST )
{
Position Tmp;
if( !BST )
printf("要删除的元素未找到");
else if( X < BST->Data )
BST->Left = Delete( X, BST->Left); /* 左子树递归删除 */
else if( X > BST->Data )
BST->Right = Delete( X, BST->Right); /* 右子树递归删除 */
else /*找到要删除的结点 */
if( BST->Left && BST->Right )
{ /*被删除结点有左右两个子结点 */
Tmp = FindMin( BST->Right );                 /*在右子树中找最小的元素填充删除结点*/
BST->Data = Tmp->Data;
BST->Right = Delete( BST->Data, BST->Right);         /*在删除结点的右子树中删除最小元素*/
}
else { /*被删除结点有一个或无子结点*/
Tmp = BST;
if( !BST->Left ) /* 有右孩子或无子结点*/
BST = BST->Right;
else if( !BST->Right ) /*有左孩子或无子结点*/
BST = BST->Left;
free( Tmp );
}
return BST;
}

二叉查找树结构由于树的深度过大而造成磁盘I/O读写过于频繁,进而导致查询效率低下.那么如何提高效率,即如何避免磁盘过于频繁的多次查找呢?根据磁盘查找存取的次数往往由树的高度所决定,所以,只要我们通过某种较好的树结构减少树的结构尽量减少树的高度。这样的树就是:平衡二叉树

各种树
平衡二叉树
B-和B+树的定义、性质特点、举例说明
线索二叉树
哈夫曼树Huffman Tree

二叉搜索树/二叉排序树/二叉查找树相关推荐

  1. 详解二叉排序树(二叉搜索树、二叉查找树)以及Python实现相关操作

    二叉排序树 引言 1.定义 2.性质 3.操作 3.1 查找 3.2 插入 3.3 生成 3.4 删除 引言 如何更加高效的完成对数据的查询和添加操作,例如↓↓↓ 给你一个数列 (7, 3, 10, ...

  2. 二叉排序树(二叉搜索树,二叉查找树)

    递归实现二叉搜索树(BST)的创建 以数组的形式实现(循环) 以递归的形式实现

  3. Binary Search Tree(二叉搜索树、二叉查找树、二叉排序树)

    搜索树数据结构支持许多动态几何操作,包括SEARCH.MININUM.MAXINUM.PREDECESSOR.SUCCESSOR.INSERT和DELETE等.因此,我们可以使用一个搜索树作为字典或者 ...

  4. 二叉搜索树 java_二叉查找树之 Java的实现【下】

    /** * Java 语言: 二叉查找树 * * @author skywang * @date 2013/11/07 */ public class BSTree>{ private BSTN ...

  5. 递归1:二叉搜索树的范围和

    给定二叉搜索树的根结点 root,返回 L 和 R(含)之间的所有结点的值的和. 二叉搜索树保证具有唯一的值. 示例 1: 输入:root = [10,5,15,3,7,null,18], L = 7 ...

  6. 数据结构与算法之二叉搜索树

    与链表不同,树是一种非线性的数据结构.树中最常用的是二叉树,二叉树限制了子树的数量,也就是每个结点的子树至多2个,并且这两个子树是有顺序的.而二叉搜索树(二叉查找树,二叉排序树)是指根节点的关键字大于 ...

  7. leetcode - 96. 不同的二叉搜索树

    96. 不同的二叉搜索树 ------------------------------------------ 给定一个整数 n,求以 1 - n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 ...

  8. 二叉搜索树的2层结点统计_植树节,程序猿种的那些树

    公历 3 月 12 日是一年一度的植树节.旨在宣传保护森林,并动员群众参加植树造林活动.说到树,程序猿们肯定不陌生,趁着这个植树节到来之时普及一下程序猿们经常遇见的树. 1. 二叉搜索树 定义 二叉搜 ...

  9. 二叉搜索树,二叉平衡术,红黑树,B树,B+树

    二叉搜索树 二叉搜索树 平衡二叉树 红黑树 B树 B+树 二叉搜索树 二叉排序树定义: 二叉排序树或者是空树或者是满足以下条件: 1)若它的左子树不空,则左子树上的所有关键字小于根关键字的值 2)若它 ...

最新文章

  1. .Net Core MVC初学习
  2. 从CV到ML 直播场景下新技术的应用
  3. 写聊天室之前 了解聊天室拓展出来的各种知识点
  4. Android平台监听系统截屏方案预研及相关知识点
  5. xib 设置阴影_使用“IBInspectable”XIB设置圆角、边框、阴影
  6. 你绝对想不到R文件找不到(cannot resolve symbol R)的原因
  7. Log4j的组件和配置文件介绍
  8. SAP Hybris Commerce里的数据库表
  9. 巨一自动化工业机器人_2021第11届深圳国际工业自动化及机器人展览会
  10. alchemy php,Flask SQLAlchemy
  11. 生产上完成TopN统计流程
  12. apache httpd mysql_Centos7安装配置Apache(httpd)+php+mysql+phpMyAdmin
  13. java将图片上传数据库_〔技巧实例〕轻松实现将上传图片到数据库
  14. 高并发网络编程之epoll(个人遇到最好理解的一篇文章、易懂)
  15. 特斯拉又烧一辆!车库里起火 所幸无人受伤
  16. python工具包: pandas
  17. 【原生JS】web原生文字轮播效果
  18. matlab动力学系统仿真 教程,MATLAB/SIMULINK动力学系统建模与仿真
  19. 【语言-c#】应用程序正常初始化(0xc000007b)失败。请单击“确定”,终止应用程序。
  20. 《爱的五种能力》阅读笔记(完整版)

热门文章

  1. 五种常用设计模式的python实现:单例、工厂、构建者、代理、观察模式
  2. hadoop作业全流程图解
  3. 臀大肌(06):跪撑举臂抬腿
  4. java poi 图片 内存溢出_解决java poi海量数据导出内存溢出问题
  5. 基于mips内核的Atheros芯片--wlan中的VAP的创建
  6. FPGA基础知识 2(Xilinx/Altera FPGA 中的逻辑资源--Slices VS LE 比较)
  7. k8s 使用 calico 作为 CNI ,calico-node 启动失败
  8. Oracle数据类型转换
  9. oracle浮点型数据类型,ORACLE的数据类型float(b)
  10. 西南交通大学计算机相关专业考研科目及概述