二叉排序树的递归查找算法:
BSTNode* SearchBSTNode(BSTNode T, ElemType key)
{
if (T == NULL)
return NULL;
if (key > T->data) //查找右子树
return SearchBSTNode(T->rchild, key);
else if (key < T->data) //查找左子树
return SearchBSTNode(T->lchild, key);
else
return T;
}
当然了,通过非递归方法也是可以的;
下面是非递归的算法:
BSTNode* Search_BST(BSTNode T, ElemType key)
{
while (T != NULL)
{
if (p->data == key)
return p; //等于根结点
p = (key < p->data) ? p->lchild : p->rchild; //进行左右子树的查找
}
return T;
}
二叉排序树的查找效率分析:
二叉排序树的查找效率主要取决于树的高度(分三种情况);
1、若二叉排序树的左右子树高度之差的绝对值不超过1,则这样的二叉排序树成为平衡二叉树: 1 n ∑ n = 1 N ( 2 i + 1 ∗ i ) \frac1n\sum_{n=1}N{(2{i+1}*i)} n1n=1∑N(2i+1∗i)
即它的平均查找长度为O( log 2 n \log_2{n} log2n);
2、若二叉排序树为只有一个左子树或者右子树的单只树(类似于有序的单链表): 1 n ∑ n = 1 N i \frac1n\sum_{n=1}^N{i} n1n=1∑Ni
即其平均查找长度为O(n);
3、若二叉排序树为正常二叉排序树,则其平均查找长度为 1 n ∑ n = 1 N n i c i \frac1n\sum_{n=1}^N{n_ic_i} n1n=1∑Nnici
首先要知道,二叉排序树作为一种动态树表,其特点就是树的结构通常不是一次生成的,而是在查找的过程中,当树种不存在关键字值等于给定值的结点时在进行插入的;
插入结点的过程:若原二叉树为空,则直接插入结点;否则,若关键字 k 小于根结点值,则插入到左子树,若关键字 k 大于根结点值,则插入到右子树。
【注】插入的结点一定是一个新添加的叶子结点,且是查找失败时的查找路径上访问的最后一个结点的左孩子或右孩子。
二叉排序树的插入算法:
int Insert_BST(BiTree &T, KeyType k)
{
if (T == NULL) //原树为空,新插入的记录为根结点
{
T = (BiTree*)malloc(sizeof(BSTNode);
T->key = k;
T->lchild = T->rchild = NULL;
return true;
}
else if (k == T->key)
return false; //存在相同关键字的结点,插入失败
else if (k < T->key)
return Insert_BST(T->lchild, k); //插入到左子树
else
return Insert_BST(T->rchild, k); //插入到右子树
}
二叉排序树的构造其实就是一个空树将元素依次进行插入到相应位置的过程;
构造二叉排序树的算法:
void Creat_BST(BiTree &T, KeyType str[], int n)
{
T == NULL; //初始化 T 为空树
int i = 0;
while(i < n){
Insert_BST(T, str[i]); //依次将每个关键字插入到二叉排序树中
i++;
}
}
在二叉排序树中删除一个结点时,不能把以该结点为根节点的子树上的结点都删除,必须先把被删除结点从存储二叉排序树的链表上摘下,将因删除结点二断开的二叉链表重新链接起来,同时需要保持二叉排序树的性质不会丢失。由此删除操作的实现过程按3种情况来处理(设被删除结点为 z ):
1、删除结点为叶结点,直接删除;
2、删除结点只有一棵左子树或者右子树,则让 z 的子树成为 z 父结点的子树(即替代 z 位置);
3、删除结点有左右两棵子树,则需要令 z 的直接后继或者直接前驱替代 z ,然后从二叉排序树中删去这个直接后继或直接前驱,这样就转化为第一或第二种情况了。
二叉排序树的删除算法如下:
void Delete_BSTNode( BiTree T, ElemType key)
{
BiTree p, q;
p = T;
ElemType temp;
while( NULL != p && key != p->data ) {
q = p;
if( key < p->data )
p = p->lchild ;
else
p = p->rchild ;
}
if( NULL == p )
printf(“无此元素!\n”);
else {
//情况1:结点p的双亲结点为q,且p为叶子结点,则直接将其删除。
if( NULL == p->lchild && NULL == p->rchild ) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。


既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频



《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
时间:简历模板+Java面试题+热门技术系列教程视频
[外链图片转存中…(img-WhcMU9jt-1713511606822)]
[外链图片转存中…(img-v0RxNrOh-1713511606823)]
[外链图片转存中…(img-6xhWw1Ss-1713511606823)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
本文详细介绍了二叉排序树的递归和非递归查找算法,探讨了不同情况下查找效率,并涉及二叉树的插入、构造和删除操作。重点在于理解如何维护二叉排序树的特性以保持高效性能。
574

被折叠的 条评论
为什么被折叠?



