二叉排序树的算法实现

合集下载

二叉排序树

二叉排序树

9
第9章
第三节
二、二叉排序树(插入)

查找
动态查找表
二叉排序树是一种动态查找表


当树中不存在查找的结点时,作插入操作
新插入的结点一定是叶子结点(只需改动一个 结点的指针) 该叶子结点是查找不成功时路径上访问的最后 一个结点的左孩子或右孩子(新结点值小于或 大于该结点值) 10

第9章
第三节
查找
19
在二叉排序树中查找关 键字值等于37,88,94
3
第9章
第三节
查找
动态查找表
二、二叉排序树(查找函数)中结点结构定义 二叉排序树通常采用二叉链表的形式进行存 储,其结点结构定义如下:
typedef struct BiNode { int data; BiNode *lChild, *rChild; }BiNode,*BitTree;
4
第9章
第三节
查找
动态查找表
2、二叉排序树的定义 定义二叉排序树所有用到的变量 BitTree root; int
//查找是否成功(1--成功,0--不成功) //查找位置(表示在BisCount层中的第几个位置
BisSuccess;
int
int
BisPos;
BisCount;
//查找次数(相当于树的层数)
7
第9章
第三节
查找
动态查找表
二、二叉排序树(查找函数)
else { BisSuccess = 0; root=GetNode(k);//查找不成功,插入新的结点}
} BiNode * GetNode(int k) { BiNode *s; s = new BiNode; s->data = k; s->lChild = NULL; s->rChild = NULL; return(s);}

二叉排序树

二叉排序树

②若*p结点只有左子树,或只有右子树,则可将*p的左子 树或右子树直接改为其双亲结点*f的左子树,即: f->1child=p->1child(或f->1child=p->rchild); free(p); *f
F *p P P1
*f
F
*f
F *p P
*f
F
Pr
P1
Pr
③若*p既有左子树,又有右子树。则:
-1 0
47
-1
47
47
0
31 69
69
25
0
47
0
25
0
47
-1 0
31
0
69
0
40
69
40
69
0
25 76
40
76
(a)
AL、BL、BR 都是空树
(b) AL、BL、BR 都是非空树
LR型调整操作示意图
2
A
-1
0
C
AR C BL CL CR AR
0 0
B BL CL S
B
A
CR
(a) 插入结点*s后失去平衡
31
0 0 -1
31
0 1
28
0
25
0 0
47
0
25
-1
47
0
25
0
31
0
16 0
28
16
28
0
16 30
30
47
(c) LR(R)型调整
RL型调整操作示意图
A B C A BR CR B BR
AL
C
AL
CL CR

数据结构 二叉排序树

数据结构 二叉排序树

9.6.2 哈希函数的构造方法
构造哈希函数的目标:
哈希地址尽可能均匀分布在表空间上——均 匀性好; 哈希地址计算尽量简单。
考虑因素:
函数的复杂度; 关键字长度与表长的关系; 关键字分布情况; 元素的查找频率。
一、直接地址法 取关键字或关键字的某个线性函数值为哈希地址 即: H(key) = key 或: H(key) = a* key + b 其中,a, b为常数。 例:1949年后出生的人口调查表,关键字是年份 年份 1949 1950 1951 … 人数 … … … …
9.4 二叉排序树
1.定义:
二叉排序树(二叉搜索树或二叉查找树) 或者是一棵空树;或者是具有如下特性的二叉树
(1) 若它的左子树不空,则左子树上所有结点的 值均小于根结点的值;
(2) 若它的右子树不空,则右子树上所有结点 的值均大于等于根结点的值; (3) 它的左、右子树也都分别是二叉排序树。
例如:
H(key)
通常设定一个一维数组空间存储记录集合,则 H(key)指示数组中的下标。
称这个一维数组为哈希(Hash)表或散列表。 称映射函数 H 为哈希函数。 H(key)为哈希地址
例:假定一个线性表为: A = (18,75,60,43,54,90,46) 假定选取的哈希函数为
hash3(key) = key % 13
H(key) = key + (-1948) 此法仅适合于: 地址集合的大小 = = 关键字集合的大小
二、数字分析法
假设关键字集合中的每个关键字都是由 s 位数 字组成 (u1, u2, …, us),分析关键字集中的全体, 并从中提取分布均匀的若干位或它们的组合作为 地址。 例如:有若干记录,关键字为 8 位十进制数, 假设哈希表的表长为100, 对关键字进行分析, 取随机性较好的两位十进制数作为哈希地址。

二叉排序树

二叉排序树

二叉排序树1.二叉排序树定义二叉排序树(Binary Sort Tree)或者是一棵空树;或者是具有下列性质的二叉树:(1)若左子树不空,则左子树上所有结点的值均小于根结点的值;若右子树不空,则右子树上所有结点的值均大于根结点的值。

(2)左右子树也都是二叉排序树,如图6-2所示。

2.二叉排序树的查找过程由其定义可见,二叉排序树的查找过程为:(1)若查找树为空,查找失败。

(2)查找树非空,将给定值key与查找树的根结点关键码比较。

(3)若相等,查找成功,结束查找过程,否则:①当给值key小于根结点关键码,查找将在以左孩子为根的子树上继续进行,转(1)。

②当给值key大于根结点关键码,查找将在以右孩子为根的子树上继续进行,转(1)。

3.二叉排序树插入操作和构造一棵二叉排序树向二叉排序树中插入一个结点的过程:设待插入结点的关键码为key,为将其插入,先要在二叉排序树中进行查找,若查找成功,按二叉排序树定义,该插入结点已存在,不用插入;查找不成功时,则插入之。

因此,新插入结点一定是作为叶子结点添加上去的。

构造一棵二叉排序树则是逐个插入结点的过程。

对于关键码序列为:{63,90,70,55,67,42,98,83,10,45,58},则构造一棵二叉排序树的过程如图6-3所示。

4.二叉排序树删除操作从二叉排序树中删除一个结点之后,要求其仍能保持二叉排序树的特性。

设待删结点为*p(p为指向待删结点的指针),其双亲结点为*f,删除可以分三种情况,如图6-4所示。

(1)*p结点为叶结点,由于删去叶结点后不影响整棵树的特性,所以,只需将被删结点的双亲结点相应指针域改为空指针,如图6-4(a)所示。

(2)*p结点只有右子树或只有左子树,此时,只需将或替换*f结点的*p子树即可,如图6-4(b)、(c)所示。

(3)*p结点既有左子树又有右子树,可按中序遍历保持有序地进行调整,如图6-4(d)、(e)所示。

设删除*p结点前,中序遍历序列为:① P为F的左子女时有:…,Pi子树,P,Pj,S子树,Pk,Sk子树,…,P2,S2子树,P1,S1子树,F,…。

二叉排序树的实验报告

二叉排序树的实验报告

二叉排序树的实验报告二叉排序树的实验报告引言:二叉排序树(Binary Search Tree,简称BST)是一种常用的数据结构,它将数据按照一定的规则组织起来,便于快速的查找、插入和删除操作。

本次实验旨在深入了解二叉排序树的原理和实现,并通过实验验证其性能和效果。

一、实验背景二叉排序树是一种二叉树,其中每个节点的值大于其左子树的所有节点的值,小于其右子树的所有节点的值。

这种特性使得在二叉排序树中进行查找操作时,可以通过比较节点的值来确定查找的方向,从而提高查找效率。

二、实验目的1. 理解二叉排序树的基本原理和性质;2. 掌握二叉排序树的构建、插入和删除操作;3. 验证二叉排序树在查找、插入和删除等操作中的性能和效果。

三、实验过程1. 构建二叉排序树首先,我们需要构建一个空的二叉排序树。

在构建过程中,我们可以选择一个节点作为根节点,并将其他节点插入到树中。

插入节点时,根据节点的值与当前节点的值进行比较,如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。

重复这个过程,直到所有节点都被插入到树中。

2. 插入节点在已有的二叉排序树中插入新的节点时,我们需要遵循一定的规则。

首先,从根节点开始,将新节点的值与当前节点的值进行比较。

如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。

如果新节点的值与当前节点的值相等,则不进行插入操作。

3. 删除节点在二叉排序树中删除节点时,我们需要考虑不同的情况。

如果要删除的节点是叶子节点,即没有左右子树,我们可以直接删除该节点。

如果要删除的节点只有一个子树,我们可以将子树连接到要删除节点的父节点上。

如果要删除的节点有两个子树,我们可以选择将其右子树中的最小节点或左子树中的最大节点替代该节点,并删除相应的替代节点。

四、实验结果通过对二叉排序树的构建、插入和删除操作的实验,我们得到了以下结果:1. 二叉排序树可以高效地进行查找操作。

二叉排序树的删除算法

二叉排序树的删除算法

二叉排序树(Binary Search Tree,简称BST)是一种特殊的二叉树,它的每个节点的值满足以下性质:
1.左子树上所有节点的值均小于根节点的值。

2.右子树上所有节点的值均大于根节点的值。

3.左、右子树也分别为二叉排序树。

为了删除一个节点,我们首先需要找到需要删除的节点,然后按照一定的规则替换这个节点,以保持二叉排序树的性质。

以下是二叉排序树的删除算法:1.查找要删除的节点:从根节点开始,按照二叉排序树的性质查找要删除的
节点。

2.删除节点:
o如果要删除的节点是叶子节点(没有左右子节点),直接删除即可。

o如果要删除的节点只有一个子节点,用它的子节点替换它。

o如果要删除的节点有两个子节点,找到它的前驱节点或后继节点(根据二叉排序树的性质),用前驱节点或后继节点替换它,然后删除前
驱节点或后继节点。

3.调整树:根据需要,对树进行调整,以保持二叉排序树的性质。

需要注意的是,在删除节点时,需要小心处理左右子节点的边界情况。

如果一个节点的左子节点为空,那么它的左子节点就是它的前驱节点;如果它的右子节点为空,那么它的右子节点就是它的后继节点。

二叉排序树

二叉排序树

就维护表的有序性而言,二叉排序树无须移 动结点,只需修改指针即可完成插入和删 除操作,且其平均的执行时间均为O(lgn), 因此更有效。二分查找所涉及的有序表是 一个向量,若有插入和删除结点的操作, 则维护表的有序性所花的代价是O(n)。当 有序表是静态查找表时,宜用向量作为其 存储结构,而采用二分查找实现其查找操 作;若有序表里动态查找表,则应选择二 叉排序树作为其存储结构。
if(q->lchild) //*q的左子树非空,找*q的左子 树的最右节点r. {for(q=q->lchild;q->rchild;q=q->rchild); q->rchild=p->rchild; } if(parent->lchild==p)parent->lchild=p>lchild; else parent->rchild=p->lchild; free(p); /释放*p占用的空间 } //DelBSTNode
下图(a)所示的树,是按如下插入次序构成的: 45,24,55,12,37,53,60,28,40,70 下图(b)所示的树,是按如下插入次序构成的: 12,24,28,37,40,45,53,55,60,70
在二叉排序树上进行查找时的平均查找长度和二叉树的形态 有关: ①在最坏情况下,二叉排序树是通过把一个有序表的n 个结点依次插入而生成的,此时所得的二叉排序树蜕化为 棵深度为n的单支树,它的平均查找长度和单链表上的顺 序查找相同,亦是(n+1)/2。 ②在最好情况下,二叉排序树在生成的过程中,树的形 态比较匀称,最终得到的是一棵形态与二分查找的判定树 相似的二叉排序树,此时它的平均查找长度大约是lgn。 ③插入、删除和查找算法的时间复杂度均为O(lgn)。 (3)二叉排序树和二分查找的比较 就平均时间性能而言,二叉排序树上的查找和二分查找 差不多。

数据结构二叉排序树

数据结构二叉排序树

05
13
19
21
37
56
64
75
80
88
92
low mid high 因为r[mid].key<k,所以向右找,令low:=mid+1=4 (3) low=4;high=5;mid=(4+5) div 2=4
05
13
19
low
21
37
56
64
75
80
88
92
mid high
因为r[mid].key=k,查找成功,所查元素在表中的序号为mid 的值
平均查找长度:为确定某元素在表中某位置所进行的比 较次数的期望值。 在长度为n的表中找某一元素,查找成功的平均查找长度:
ASL=∑PiCi
Pi :为查找表中第i个元素的概率 Ci :为查到表中第i个元素时已经进行的比较次数
在顺序查找时, Ci取决于所查元素在表中的位置, Ci =i,设每个元素的查找概率相等,即Pi=1/n,则:
RL型的第一次旋转(顺时针) 以 53 为轴心,把 37 从 53 的左上转到 53 的左下,使得 53 的左 是 37 ;右是 90 ,原 53 的左变成了 37 的右。 RL型的第二次旋转(逆时针)
一般情况下,假设由于二叉排序树上插入结点而失去 平衡的最小子树的根结点指针为a(即a是离插入结点最 近,且平衡因子绝对值超过1的祖先结点),则失去平衡 后进行调整的规律可归纳为下列四种情况: ⒈RR型平衡旋转: a -2 b -1 h-1 a1
2.查找关键字k=85 的情况 (1) low=1;high=11;mid=(1+11) / 2=6
05
13
19
21
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

韩山师范学院
实验题目:
二叉排序树的算法实现
班级:2015级软工班作者:黄俊聪
#include<iostream>
using namespace std;
#define ENDFLAG 0
typedefintKeyType;
typedefintInfoType;
typedefstructBSTNode
{
KeyType data;//每个结点的数据域包括关键字项和其他数据项
structBSTNode *lchild,*rchild;//左右孩子指针
InfoTypeotherinfo;//其他数据项
}BSTNode,*BSTree;
voidInsertBST(BSTree&T,int key)
{//当二叉排序树T中不存在关键字等于e.key的数据元素,则插入该元素BSTree S;
if(!T)
{//找到插入位置,递归结束
S=new BSTNode;//生成新结点*S
S->data=key;//新结点*S的数据域为e
S->lchild=S->rchild=NULL;//新结点*S作为叶子结点
T=S;//把新结点*S链接到已找到的插入位置
}
else if(key<T->data)
InsertBST(T->lchild,key);//将*S插入左子树
else if(key>T->data)
InsertBST(T->rchild,key);//将*S插入右子树
}
voidCreatBST(BSTree& T)
{
int key;
T=NULL;//将二叉排序树T初始化为空树
cout<<"请输入元素:"<<endl;
cin>>key;
while(key!=ENDFLAG)//ENDFLAG为自定义常亮,作为输入结束标志
{
InsertBST(T,key);//将此结点插入二叉排序树T中
cin>>key;
}
cout<<"创建成功:"<<endl;
}
voidDeleteBST(BSTree&T,KeyType key)
{
BSTreep,f,q,s;
p=T;
f=NULL;//初始化
/*------下面的while循环从根开始查找关键字等于key的结点*p--------*/ while(p)
{
if(p->data==key)
break;//找到关键字等于key的结点*p,结束循环
f=p;//*f为*p的双亲结点
if(p->data>key)
p=p->lchild;//在*P的左子树中继续查找
else
p=p->rchild;//在*P的右子树中继续查找
}
if(!p)
return;
/*---考虑3中情况实现P所指向子树内部的处理:*P左右子树均不空、无右子树、无左子树---*/
q=p;
if((p->lchild)&&(p->rchild))//被删除结点*P左右子树均不空
{
s=p->lchild;
while(s->rchild)//在*P的左子树中据需查找其前驱结点,即最右下结点
{
q=s;
s=s->rchild;//向右到尽头
}
p->data=s->data;//S指向被删除结点的"前驱"
if(q!=p)
q->rchild=s->lchild;//重接*q的右子树
else
q->lchild=s->lchild;//重接*q的左子树
delete s;
return;
}
else if(!p->rchild)//被删除结点*P无右子树,只需重接其左子树
{
p=p->lchild;
}
else if(!p->lchild)//被删结点*P无左子树,只需重接其右子树
{
p=p->rchild;
}
/*-----将P所指的子树挂接到其双亲结点*f相应的位置---*/
if(!f)
T=p;//被删除结点为根结点
else if(q==f->lchild)
f->lchild=p;//挂接到*f的左子树位置
else
f->rchild=p;//挂接到*f的右子树位置
delete q;
}
BSTreeSearchBST(BSTreeT,KeyType key)
{//在跟指针T所指二叉排序树中递归地查找某关键字等于key的数据元素//若查找成功,则返回指向改数据元素结点的指针,否则返回空指针if(!T||key==T->data)
return T;//查找结束
else if(key<T->data)
return SearchBST(T->lchild,key);//在左子树中继续查找else
return SearchBST(T->lchild,key);//在右子树中继续查找
}
void Print(BSTree T)
{
if(T)
{
Print(T->lchild);
cout<<"此时树为:"<<T->data<<" "<<endl;
Print(T->rchild);
}
}
int main()
{
BSTree T;
int n;
int key;
cout<<"****1.创建****"<<endl;
cout<<"* 2.查找*"<<endl;
cout<<"* 3.插入*"<<endl;
cout<<"* 4.删除*"<<endl;
cout<<"* 5.输出*"<<endl;
cout<<"****6.结束****"<<endl;
cout<<"请输入要操作的功能序号:"<<endl;
cin>>n;
while(1)
{
switch(n)
{
case 1:
CreatBST( T);
break;
case 2:
cout<<"请输入要查找的元素:"<<endl;
cin>>key;
SearchBST(T,key);
cout<<"查找成功"<<endl;
break;
case 3:
cout<<"请输入要插入的元素:"<<endl;
cin>>key;
InsertBST(T,key);
cout<<"插入成功"<<endl;
break;
case 4:
cout<<"请输入要删除的元素:"<<endl;
cin>>key;
DeleteBST(T,key);
cout<<"删除成功"<<endl;
break;
case 5:
Print(T);
break;
case 6:
exit(0);
default:
cout<<"输入有误,请重新输入:"<<endl;
}
cout<<"请输入要操作的功能序号:"<<endl;
cin>>n;
}
}。

相关文档
最新文档