二叉排序树的创建、删除、插入等操作
数据结构平衡二叉树的操作演示
平衡二叉树操作的演示1.需求分析本程序是利用平衡二叉树,实现动态查找表的基本功能:创建表,查找、插入、删除。
具体功能:(1)初始,平衡二叉树为空树,操作界面给出创建、查找、插入、删除、合并、分裂六种操作供选择。
每种操作均提示输入关键字。
每次插入或删除一个结点后,更新平衡二叉树的显示。
(2)平衡二叉树的显示采用凹入表现形式。
(3)合并两棵平衡二叉树。
(4)把一棵二叉树分裂为两棵平衡二叉树,使得在一棵树中的所有关键字都小于或等于x,另一棵树中的任一关键字都大于x。
如下图:2.概要设计平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。
具体步骤:(1)每当插入一个新结点,从该结点开始向上计算各结点的平衡因子,即计算该结点的祖先结点的平衡因子,若该结点的祖先结点的平衡因子的绝对值不超过1,则平衡二叉树没有失去平衡,继续插入结点;(2)若插入结点的某祖先结点的平衡因子的绝对值大于1,则找出其中最小不平衡子树的根结点;(3)判断新插入的结点与最小不平衡子树的根结点个关系,确定是那种类型的调整;(4)如果是LL型或RR型,只需应用扁担原理旋转一次,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;如果是LR型或RL型,则需应用扁担原理旋转两次,第一次最小不平衡子树的根结点先不动,调整插入结点所在子树,第二次再调整最小不平衡子树,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;(5)计算调整后的平衡二叉树中各结点的平衡因子,检验是否因为旋转而破坏其他结点的平衡因子,以及调整后平衡二叉树中是否存在平衡因子大于1的结点。
流程图3.详细设计二叉树类型定义:typedef int Status;typedef int ElemType;typedef struct BSTNode{ElemType data;int bf;struct BSTNode *lchild ,*rchild;} BSTNode,* BSTree;Status SearchBST(BSTree T,ElemType e)//查找void R_Rotate(BSTree &p)//右旋void L_Rotate(BSTree &p)//左旋void LeftBalance(BSTree &T)//插入平衡调整void RightBalance(BSTree &T)//插入平衡调整Status InsertAVL(BSTree &T,ElemType e,int &taller)//插入void DELeftBalance(BSTree &T)//删除平衡调整void DERightBalance(BSTree &T)//删除平衡调整Status Delete(BSTree &T,int &shorter)//删除操作Status DeleteAVL(BSTree &T,ElemType e,int &shorter)//删除操作void merge(BSTree &T1,BSTree &T2)//合并操作void splitBSTree(BSTree T,ElemType e,BSTree &T1,BSTree &T2)//分裂操作void PrintBSTree(BSTree &T,int lev)//凹入表显示附录源代码:#include<stdio.h>#include<stdlib.h>//#define TRUE 1//#define FALSE 0//#define OK 1//#define ERROR 0#define LH +1#define EH 0#define RH -1//二叉类型树的类型定义typedef int Status;typedef int ElemType;typedef struct BSTNode{ElemType data;int bf;//结点的平衡因子struct BSTNode *lchild ,*rchild;//左、右孩子指针} BSTNode,* BSTree;/*查找算法*/Status SearchBST(BSTree T,ElemType e){if(!T){return 0; //查找失败}else if(e == T->data ){return 1; //查找成功}else if (e < T->data){return SearchBST(T->lchild,e);}else{return SearchBST(T->rchild,e);}}//右旋void R_Rotate(BSTree &p){BSTree lc; //处理之前的左子树根结点lc = p->lchild; //lc指向的*p的左子树根结点p->lchild = lc->rchild; //lc的右子树挂接为*P的左子树lc->rchild = p;p = lc; //p指向新的根结点}//左旋void L_Rotate(BSTree &p){BSTree rc;rc = p->rchild; //rc指向的*p的右子树根结点p->rchild = rc->lchild; //rc的左子树挂接为*p的右子树rc->lchild = p;p = rc; //p指向新的根结点}//对以指针T所指结点为根结点的二叉树作左平衡旋转处理,//本算法结束时指针T指向新的根结点void LeftBalance(BSTree &T){BSTree lc,rd;lc=T->lchild;//lc指向*T的左子树根结点switch(lc->bf){ //检查*T的左子树的平衡度,并做相应的平衡处理case LH: //新结点插入在*T的左孩子的左子树,要做单右旋处理T->bf = lc->bf=EH;R_Rotate(T);break;case RH: //新结点插入在*T的左孩子的右子树上,做双旋处理rd=lc->rchild; //rd指向*T的左孩子的右子树根switch(rd->bf){ //修改*T及其左孩子的平衡因子case LH: T->bf=RH; lc->bf=EH;break;case EH: T->bf=lc->bf=EH;break;case RH: T->bf=EH; lc->bf=LH;break;}rd->bf=EH;L_Rotate(T->lchild); //对*T的左子树作左旋平衡处理R_Rotate(T); //对*T作右旋平衡处理}}//右平衡旋转处理void RightBalance(BSTree &T){BSTree rc,ld;rc=T->rchild;switch(rc->bf){case RH:T->bf= rc->bf=EH;L_Rotate(T);break;case LH:ld=rc->lchild;switch(ld->bf){case LH: T->bf=RH; rc->bf=EH;break;case EH: T->bf=rc->bf=EH;break;case RH: T->bf = EH; rc->bf=LH;break;}ld->bf=EH;R_Rotate(T->rchild);L_Rotate(T);}}//插入结点Status InsertAVL(BSTree &T,ElemType e,int &taller){//taller反应T长高与否if(!T){//插入新结点,树长高,置taller为trueT= (BSTree) malloc (sizeof(BSTNode));T->data = e;T->lchild = T->rchild = NULL;T->bf = EH;taller = 1;}else{if(e == T->data){taller = 0;return 0;}if(e < T->data){if(!InsertAVL(T->lchild,e,taller))//未插入return 0;if(taller)//已插入到*T的左子树中且左子树长高switch(T->bf){//检查*T的平衡度,作相应的平衡处理case LH:LeftBalance(T);taller = 0;break;case EH:T->bf = LH;taller = 1;break;case RH:T->bf = EH;taller = 0;break;}}else{if (!InsertAVL(T->rchild,e,taller)){return 0;}if(taller)//插入到*T的右子树且右子树增高switch(T->bf){//检查*T的平衡度case LH:T->bf = EH;taller = 0;break;case EH:T->bf = RH;taller = 1;break;case RH:RightBalance(T);taller = 0;break;}}}return 1;}void DELeftBalance(BSTree &T){//删除平衡调整BSTree lc,rd;lc=T->lchild;switch(lc->bf){case LH:T->bf = EH;//lc->bf= EH;R_Rotate(T);break;case EH:T->bf = EH;lc->bf= EH;R_Rotate(T);break;case RH:rd=lc->rchild;switch(rd->bf){case LH: T->bf=RH; lc->bf=EH;break;case EH: T->bf=lc->bf=EH;break;case RH: T->bf=EH; lc->bf=LH;break;}rd->bf=EH;L_Rotate(T->lchild);R_Rotate(T);}}void DERightBalance(BSTree &T) //删除平衡调整{BSTree rc,ld;rc=T->rchild;switch(rc->bf){case RH:T->bf= EH;//rc->bf= EH;L_Rotate(T);break;case EH:T->bf= EH;//rc->bf= EH;L_Rotate(T);break;case LH:ld=rc->lchild;switch(ld->bf){case LH: T->bf=RH; rc->bf=EH;break;case EH: T->bf=rc->bf=EH;break;case RH: T->bf = EH; rc->bf=LH;break;}ld->bf=EH;R_Rotate(T->rchild);L_Rotate(T);}}void SDelete(BSTree &T,BSTree &q,BSTree &s,int &shorter){if(s->rchild){SDelete(T,s,s->rchild,shorter);if(shorter)switch(s->bf){case EH:s->bf = LH;shorter = 0;break;case RH:s->bf = EH;shorter = 1;break;case LH:DELeftBalance(s);shorter = 0;break;}return;}T->data = s->data;if(q != T)q->rchild = s->lchild;elseq->lchild = s->lchild;shorter = 1;}//删除结点Status Delete(BSTree &T,int &shorter){ BSTree q;if(!T->rchild){q = T;T = T->lchild;free(q);shorter = 1;}else if(!T->lchild){q = T;T= T->rchild;free(q);shorter = 1;}else{SDelete(T,T,T->lchild,shorter);if(shorter)switch(T->bf){case EH:T->bf = RH;shorter = 0;break;case LH:T->bf = EH;shorter = 1;break;case RH:DERightBalance(T);shorter = 0;break;}}return 1;}Status DeleteAVL(BSTree &T,ElemType e,int &shorter){ int sign = 0;if (!T){return sign;}else{if(e == T->data){sign = Delete(T,shorter);return sign;}else if(e < T->data){sign = DeleteAVL(T->lchild,e,shorter);if(shorter)switch(T->bf){case EH:T->bf = RH;shorter = 0;break;case LH:T->bf = EH;shorter = 1;break;case RH:DERightBalance(T);shorter = 0;break;}return sign;}else{sign = DeleteAVL(T->rchild,e,shorter);if(shorter)switch(T->bf){case EH:T->bf = LH;shorter = 0;break;case RH:T->bf = EH;break;case LH:DELeftBalance(T);shorter = 0;break;}return sign;}}}//合并void merge(BSTree &T1,BSTree &T2){int taller = 0;if(!T2)return;merge(T1,T2->lchild);InsertAVL(T1,T2->data,taller);merge(T1,T2->rchild);}//分裂void split(BSTree T,ElemType e,BSTree &T1,BSTree &T2){ int taller = 0;if(!T)return;split(T->lchild,e,T1,T2);if(T->data > e)InsertAVL(T2,T->data,taller);elseInsertAVL(T1,T->data,taller);split(T->rchild,e,T1,T2);}//分裂void splitBSTree(BSTree T,ElemType e,BSTree &T1,BSTree &T2){ BSTree t1 = NULL,t2 = NULL;split(T,e,t1,t2);T1 = t1;T2 = t2;return;}//构建void CreatBSTree(BSTree &T){int num,i,e,taller = 0;printf("输入结点个数:");scanf("%d",&num);printf("请顺序输入结点值\n");for(i = 0 ;i < num;i++){printf("第%d个结点的值",i+1);scanf("%d",&e);InsertAVL(T,e,taller) ;}printf("构建成功,输入任意字符返回\n");getchar();getchar();}//凹入表形式显示方法void PrintBSTree(BSTree &T,int lev){int i;if(T->rchild)PrintBSTree(T->rchild,lev+1);for(i = 0;i < lev;i++)printf(" ");printf("%d\n",T->data);if(T->lchild)PrintBSTree(T->lchild,lev+1);void Start(BSTree &T1,BSTree &T2){int cho,taller,e,k;taller = 0;k = 0;while(1){system("cls");printf(" 平衡二叉树操作的演示 \n\n");printf("********************************\n");printf(" 平衡二叉树显示区 \n");printf("T1树\n");if(!T1 )printf("\n 当前为空树\n");else{PrintBSTree(T1,1);}printf("T2树\n");if(!T2 )printf("\n 当前为空树\n");elsePrintBSTree(T2,1);printf("\n********************************************************************* *********\n");printf("T1操作:1.创建 2.插入 3.查找 4.删除 10.分裂\n");printf("T2操作:5.创建 6.插入 7.查找 8.删除 11.分裂\n");printf(" 9.合并 T1,T2 0.退出\n");printf("*********************************************************************** *******\n");printf("输入你要进行的操作:");scanf("%d",&cho);switch(cho){case 1:CreatBSTree(T1);break;case 2:printf("请输入要插入关键字的值");scanf("%d",&e);InsertAVL(T1,e,taller) ;break;case 3:printf("请输入要查找关键字的值");scanf("%d",&e);if(SearchBST(T1,e))printf("查找成功!\n");elseprintf("查找失败!\n");printf("按任意键返回87"); getchar();getchar();break;case 4:printf("请输入要删除关键字的值"); scanf("%d",&e);if(DeleteAVL(T1,e,k))printf("删除成功!\n");elseprintf("删除失败!\n");printf("按任意键返回");getchar();getchar();break;case 5:CreatBSTree(T2);break;case 6:printf("请输入要插入关键字的值"); scanf("%d",&e);InsertAVL(T2,e,taller) ;break;case 7:printf("请输入要查找关键字的值"); scanf("%d",&e);if(SearchBST(T2,e))printf("查找成功!\n");elseprintf("查找失败!\n");printf("按任意键返回");getchar();getchar();break;case 8:printf("请输入要删除关键字的值"); scanf("%d",&e);if(DeleteAVL(T2,e,k))printf("删除成功!\n");elseprintf("删除失败!\n");printf("按任意键返回");getchar();getchar();break;case 9:merge(T1,T2);T2 = NULL;printf("合并成功,按任意键返回"); getchar();getchar();break;case 10:printf("请输入要中间值字的值"); scanf("%d",&e);splitBSTree(T1,e,T1,T2) ;printf("分裂成功,按任意键返回"); getchar();getchar();break;case 11:printf("请输入要中间值字的值"); scanf("%d",&e);splitBSTree(T2,e,T1,T2) ;printf("分裂成功,按任意键返回"); getchar();getchar();break;case 0:system("cls");exit(0);}}}main(){BSTree T1 = NULL;BSTree T2 = NULL;Start(T1,T2);}。
二叉排序树
②若*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
二叉排序树的4种删除方法
二叉排序树的4种删除方法二叉排序树是一种特殊的二叉树,它的左子树中所有节点的值都小于根节点的值,右子树中所有节点的值都大于根节点的值。
在二叉排序树中,我们可以使用以下4种方法对节点进行删除操作。
1. 删除没有子节点的节点如果要删除的节点没有子节点,直接将其从父节点中删除即可。
具体步骤如下:(1)如果要删除的节点为根节点,则将其置为空。
(2)如果要删除的节点为左子节点,则将其父节点的左指针置为空。
(3)如果要删除的节点为右子节点,则将其父节点的右指针置为空。
2. 删除只有一个子节点的节点如果要删除的节点只有一个子节点,我们需要将该子节点替换到被删除位置上。
具体步骤如下:(1)如果要删除的是左子节,则用它唯一的右孩子代替它本身;(2)如果要删除的是右子节,则用它唯一左孩子代替它本身。
3. 删除有两个子结点且被删结点不是根结点当需要删除一个有两个孩子结点且不是根结点时,我们需要找到该结点右边最小值或者左边最大值来替换该结点。
具体步骤如下:(1)找到该节点右子树中的最小值或左子树中的最大值;(2)将该最小值或最大值赋给要删除的节点;(3)删除该最小值或最大值所在的节点。
4. 删除有两个子结点且被删结点是根结点当需要删除一个有两个孩子结点且是根结点时,我们需要找到该结点右边最小值或者左边最大值来替换该结点。
具体步骤如下:(1)找到该节点右子树中的最小值或左子树中的最大值;(2)将该最小值或最大值赋给要删除的节点;(3)删除该最小值或最大值所在的节点。
以上就是二叉排序树的4种删除方法,需要注意的是,在进行任何操作之前,我们必须先判断要删除的节点是否存在于二叉排序树中。
如果不存在,就不需要进行任何操作。
同时,在进行删除操作时,我们还需要考虑平衡性和稳定性等问题。
二叉排序树
二叉排序树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. 二叉排序树可以高效地进行查找操作。
二叉排序树的c语言代码
二叉排序树(Binary Sort Tree)是一种特殊的二叉树,它或左子树或右子树为完全二叉树。
由于二叉排序树的特点,其每个节点的值均大于其左子树中的所有节点的值,且小于其右子树中的所有节点的值。
以下是一个简单的二叉排序树的C语言实现,包括插入、查找和删除操作。
```c#include <stdio.h>#include <stdlib.h>typedef struct Node {int data;struct Node *left;struct Node *right;} Node;// 创建一个新的节点Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (!newNode) {printf("内存分配失败\n");return NULL;}newNode->data = data;newNode->left = newNode->right = NULL;return newNode;}// 在二叉排序树中插入一个新的节点Node* insert(Node* root, int data) {if (!root) { // 如果树为空,创建新节点并返回根节点root = createNode(data);} else if (data <= root->data) { // 如果插入的数据小于当前节点的值,则在左子树中插入root->left = insert(root->left, data);} else { // 如果插入的数据大于当前节点的值,则在右子树中插入root->right = insert(root->right, data);}return root; // 返回插入后的根节点}// 在二叉排序树中查找一个值是否存在int search(Node* root, int data) {if (!root) { // 如果树为空,返回0表示未找到return 0;} else if (root->data == data) { // 如果找到,返回1表示找到return 1;} else if (data < root->data) { // 如果插入的数据小于当前节点的值,在左子树中查找return search(root->left, data);} else { // 如果插入的数据大于当前节点的值,在右子树中查找return search(root->right, data);}}// 在二叉排序树中删除一个节点,并返回被删除的节点指针(如果存在)Node* deleteNode(Node* root, int data) {if (!root) return NULL; // 如果树为空,直接返回NULL(空树)if (data < root->data) { // 如果要删除的值小于当前节点的值,则在左子树中查找并删除root->left = deleteNode(root->left, data);} else if (data > root->data) { // 如果要删除的值大于当前节点的值,则在右子树中查找并删除root->right = deleteNode(root->right, data);} else { // 如果要删除的节点就是当前节点,根据情况选择删除方式(左子树或右子树)if (root->left == NULL) { // 如果左子树为空,直接删除当前节点(只有根节点时)Node *temp = root; // 临时保存当前节点,用于释放内存后替换原节点指针为NULLfree(temp); // 释放内存空间后将原指针设为NULL} else if (root->right == NULL) { // 如果右子树为空,直接删除当前节点(只有一个节点时)Node *temp = root->left; // 临时保存左子树的根节点,用于替换原节点指针为左子树的根节点指针(此时原节点为空)free(root); // 释放原节点的内存空间后将原指针设为NULL(此时原节点为空)root = temp; // 将原指针设为新的根节点指针(此时原节点为空)} else { // 如果左右子树都存在,则找到右子树中的最小节点(即要被替换的节点),替换原节点指针为最小节点的指针(此时原节点为空)并删除最小节点(通过递归实现)Node *temp = root->right; // 临时保存右子树的根节点指针(即要被替换的节点)root->data = temp->data; // 将原节点的数据。
数据结构-二叉排序树
二叉排序树操作一、设计步骤1)分析课程设计题目的要求2)写出详细设计说明3)编写程序代码,调试程序使其能正确运行4)设计完成的软件要便于操作和使用5)设计完成后提交课程设计报告(一)程序功能:1)创建二叉排序树2)输出二叉排序树3)在二叉排序树中插入新结点4)在二叉排序树中删除给定的值5)在二叉排序树中查找所给定的值(二)函数功能:1) struct BiTnode 定义二叉链表结点类型包含结点的信息2) class BT 二叉排序树类,以实现二叉排序树的相关操作3) InitBitree() 构造函数,使根节点指向空4) ~BT () 析构函数,释放结点空间5) void InsertBST(&t,key) 实现二叉排序树的插入功能6) int SearchBST(t,key) 实现二叉排序树的查找功能7) int DelBST(&t,key) 实现二叉排序树的删除功能8) void InorderBiTree (t) 实现二叉排序树的排序(输出功能)9) int main() 主函数,用来完成对二叉排序树类中各个函数的测试二、设计理论分析方法(一)二叉排序树定义首先,我们应该明确所谓二叉排序树是指满足下列条件的二叉树:(1)左子树上的所有结点值均小于根结点值;(2)右子数上的所有结点值均不小于根结点值;(3)左、右子数也满足上述两个条件。
根据对上述的理解和分析,我们就可以先创建出一个二叉链表结点的结构体类型(struct BiTNode)和一个二叉排序树类(class BT),以及类中的构造函数、析构函数和其他实现相关功能的函数。
(二)插入函数(void InsertBST(&t,key))首先定义一个与BiTNode<k> *BT同一类型的结点p,并为其申请空间,使p->data=key,p->lchild和p->rchild=NULL。
C平衡二叉树(AVL)创建和删除
C平衡⼆叉树(AVL)创建和删除 AVL是最先发明的⾃平衡⼆叉查找树算法。
在AVL中任何节点的两个⼉⼦⼦树的⾼度最⼤差别为⼀,所以它也被称为⾼度平衡树,n个结点的AVL树最⼤深度约1.44log2n。
查找、插⼊和删除在平均和最坏情况下都是O(log n)。
增加和删除可能需要通过⼀次或多次树旋转来重新平衡这个树。
定义 ⽤LH,EH,RH分别表⽰左⼦树⾼,等⾼,右⼦树⾼,即平衡因⼦1、0、-1#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#define LH 1 // 左⾼#define EH 0 // 等⾼#define RH -1 // 右⾼typedef struct TreeNode{int data;int bf;struct TreeNode *left, *right;}TreeNode; 旋转处理 左旋和右旋,记住“左逆右顺”就可以/************************************************* 对以*p为根的⼆叉排序树作右旋处理,处理之后p指向新的树根结点,* A B* / / \* B 旋转后变为 C A* / \ /* C D D* 即旋转处理之前的左⼦树的结点。
************************************************/void r_rotate(TreeNode **p){TreeNode *l = (*p)->left;(*p)->left = l->right;l->right = (*p);*p = l;}/************************************************* 对以*p为根的⼆叉排序树作左旋处理,处理之后p指向新的树根结点,* A B* \ / \* B 旋转后变为 A D* / \ \* C D C* 即旋转处理之前的右⼦树的结点。
数据结构 -第12周查找第3讲-二叉排序树.pdf
以二叉树或树作为表的组织形式,称为树表,它是一类动态查找表,不仅适合于数据查找,也适合于表插入和删除操作。
常见的树表:二叉排序树平衡二叉树B-树B+树9.3.1 二叉排序树二叉排序树(简称BST)又称二叉查找(搜索)树,其定义为:二叉排序树或者是空树,或者是满足如下性质(BST性质)的二叉树:❶若它的左子树非空,则左子树上所有节点值(指关键字值)均小于根节点值;❷若它的右子树非空,则右子树上所有节点值均大于根节点值;❸左、右子树本身又各是一棵二叉排序树。
注意:二叉排序树中没有相同关键字的节点。
二叉树结构满足BST性质:节点值约束二叉排序树503080209010854035252388例如:是二叉排序树。
66不试一试二叉排序树的中序遍历序列有什么特点?二叉排序树的节点类型如下:typedef struct node{KeyType key;//关键字项InfoType data;//其他数据域struct node*lchild,*rchild;//左右孩子指针}BSTNode;二叉排序树可看做是一个有序表,所以在二叉排序树上进行查找,和二分查找类似,也是一个逐步缩小查找范围的过程。
1、二叉排序树上的查找Nk< bt->keybtk> bt->key 每一层只和一个节点进行关键字比较!∧∧p查找到p所指节点若k<p->data,并且p->lchild=NULL,查找失败。
若k>p->data,并且p->rchild=NULL,查找失败。
查找失败的情况加上外部节点一个外部节点对应某内部节点的一个NULL指针递归查找算法SearchBST()如下(在二叉排序树bt上查找关键字为k的记录,成功时返回该节点指针,否则返回NULL):BSTNode*SearchBST(BSTNode*bt,KeyType k){if(bt==NULL||bt->key==k)//递归出口return bt;if(k<bt->key)return SearchBST(bt->lchild,k);//在左子树中递归查找elsereturn SearchBST(bt->rchild,k);//在右子树中递归查找}在二叉排序树中插入一个关键字为k的新节点,要保证插入后仍满足BST性质。
山东大学数据结构实验报告四
山东大学数据结构实验报告四一、引言数据结构实验报告四旨在通过实践巩固和应用所学的数据结构知识,培养学生的编程能力和问题解决能力。
本次实验的主要目的是设计并实现一个基于数据结构的应用程序,通过使用合适的数据结构和算法解决实际问题。
二、实验内容本次实验要求设计一个程序,实现以下功能:1. 输入一组整数,建立一个二叉排序树;2. 实现二叉排序树的查找、插入和删除操作;3. 对建立的二叉排序树进行中序遍历,并输出排序结果。
三、实验步骤1. 设计二叉排序树的数据结构在开始编写代码之前,我们需要先设计二叉排序树的数据结构。
二叉排序树的每个节点包含一个整数值和两个指针,分别指向左子树和右子树。
2. 实现二叉排序树的建立首先,我们需要实现一个函数,用于创建二叉排序树。
该函数根据输入的一组整数,逐个插入到二叉排序树中。
具体步骤如下:- 创建一个空的二叉排序树;- 依次读取输入的整数,并将其插入到二叉排序树中的合适位置;- 返回建立好的二叉排序树。
3. 实现二叉排序树的查找在二叉排序树中查找一个特定的值,可以使用递归或迭代的方式实现。
具体步骤如下:- 如果当前节点为空,返回空指针;- 如果当前节点的值等于目标值,返回当前节点;- 如果目标值小于当前节点的值,递归地在左子树中查找;- 如果目标值大于当前节点的值,递归地在右子树中查找。
4. 实现二叉排序树的插入在二叉排序树中插入一个新的值,需要保持二叉排序树的有序性。
具体步骤如下:- 如果树为空,将新值作为根节点插入;- 如果新值小于当前节点的值,将新值插入到左子树中;- 如果新值大于当前节点的值,将新值插入到右子树中。
5. 实现二叉排序树的删除在二叉排序树中删除一个特定的值,需要保持二叉排序树的有序性。
具体步骤如下:- 如果树为空,返回空指针;- 如果目标值小于当前节点的值,递归地在左子树中删除;- 如果目标值大于当前节点的值,递归地在右子树中删除;- 如果目标值等于当前节点的值,进行删除操作。
二叉排序树课程设计
二叉排序树课程设计一、课程目标知识目标:1. 学生能够理解二叉排序树的基本概念和性质,掌握其结构特点和应用场景。
2. 学生能够掌握二叉排序树的插入、删除和查找操作,并了解其时间复杂度。
3. 学生能够理解二叉排序树与其他排序算法的关系,了解其在排序中的应用。
技能目标:1. 学生能够运用所学知识,独立构建二叉排序树,并实现插入、删除和查找功能。
2. 学生能够分析二叉排序树的性能,对其进行优化,提高排序效率。
3. 学生能够运用二叉排序树解决实际问题,如数据排序、查找等。
情感态度价值观目标:1. 学生通过学习二叉排序树,培养对数据结构和算法的兴趣,提高解决问题的能力。
2. 学生在学习过程中,学会合作、交流,培养团队精神和共享意识。
3. 学生能够认识到二叉排序树在实际应用中的价值,激发对计算机科学的热爱。
本课程针对高中年级学生,课程性质为理论与实践相结合。
在教学过程中,注重启发式教学,引导学生主动探究、实践。
根据学生特点和教学要求,课程目标具体、可衡量,以便学生和教师能够清晰地了解课程的预期成果。
课程目标的分解为具体的学习成果,为后续的教学设计和评估提供依据。
二、教学内容1. 引入二叉排序树的概念,讲解其定义、性质和基本操作。
- 理解二叉树的基础知识,回顾二叉树的遍历方法。
- 介绍二叉排序树的定义,阐述其特点及应用场景。
- 分析二叉排序树的性质,如二叉排序树的中序遍历结果为有序序列。
2. 探讨二叉排序树的构建、插入、删除和查找操作。
- 讲解二叉排序树的构建方法,学会从无序数据建立二叉排序树。
- 分析插入、删除和查找操作的步骤,理解它们的时间复杂度。
- 举例说明如何利用二叉排序树实现数据排序和查找。
3. 分析二叉排序树的性能及优化方法。
- 探讨二叉排序树的高度、平衡因子等性能指标。
- 介绍常见的优化方法,如平衡二叉树(AVL树)和红黑树。
4. 实践环节:二叉排序树的应用。
- 设计实践题目,让学生动手实现二叉排序树的基本操作。
二叉排序树课程设计
二叉排序树课程设计一、课程目标知识目标:1. 理解二叉排序树的概念和特点;2. 掌握二叉排序树的插入、删除和查找操作;3. 能够分析二叉排序树的时间复杂度;4. 了解二叉排序树在实际应用中的优势。
技能目标:1. 能够手动构建二叉排序树并进行基本操作;2. 能够运用编程语言实现二叉排序树的基本功能;3. 能够分析并解决二叉排序树相关的问题;4. 能够运用二叉排序树解决实际排序和查找问题。
情感态度价值观目标:1. 培养学生对数据结构和算法的兴趣,激发学习热情;2. 培养学生的逻辑思维能力和问题解决能力;3. 培养学生的团队协作意识,学会与他人共同分析、解决问题;4. 培养学生严谨的科学态度,注重算法的正确性和效率。
课程性质:本课程为计算机科学领域的数据结构与算法课程,旨在让学生掌握二叉排序树的基本概念和操作,提高学生的编程能力和逻辑思维能力。
学生特点:学生具备基本的计算机知识和编程基础,对数据结构有一定了解,但对二叉排序树的认识可能较浅。
教学要求:结合学生特点,采用讲解、实践和讨论相结合的教学方法,使学生在理解二叉排序树理论知识的基础上,能够动手实践并解决实际问题。
在教学过程中,注重培养学生的自主学习能力和团队合作精神,提高学生的综合素质。
通过本课程的学习,使学生能够达到上述课程目标,为后续相关课程打下坚实基础。
二、教学内容1. 引入二叉排序树的概念,阐述其定义、性质和应用场景;- 教材章节:第三章第一节“二叉排序树的定义和性质”2. 讲解二叉排序树的插入、删除、查找操作及其实现方法;- 教材章节:第三章第二节“二叉排序树的操作”3. 分析二叉排序树的性能特点,包括时间复杂度和空间复杂度;- 教材章节:第三章第三节“二叉排序树的性能分析”4. 介绍二叉排序树在实际应用中的优势,如排序、查找等;- 教材章节:第三章第四节“二叉排序树的应用”5. 结合实例,让学生动手实践二叉排序树的构建和操作;- 教材章节:第三章实例分析与编程练习6. 总结二叉排序树的特点和适用场景,与其他排序方法进行对比;- 教材章节:第三章总结与拓展教学进度安排:1. 第1课时:引入二叉排序树的概念、性质和应用场景;2. 第2课时:讲解二叉排序树的插入、删除、查找操作;3. 第3课时:分析二叉排序树的性能特点;4. 第4课时:介绍二叉排序树在实际应用中的优势;5. 第5课时:结合实例,学生动手实践二叉排序树的构建和操作;6. 第6课时:总结二叉排序树,与其他排序方法进行对比。
第四章二叉树_2
9
二叉搜索树插入操作
利用插入操作可以构造一棵二叉搜索树 首先给出结点序列: 首先给出结点序列 13、8、23、5、18、37 、 、 、 、 、
Φ13
8 5 5 18
83 18 5 2 37 23 37 37 18
10
template<class T> void BST<T>::insertNodeHelper(const T& el) { BSTNode<T> *p = root, *prev = 0; while (p != 0) { prev = p; if( p->data < el ) p = p->rchild; else p = p->lchild; } if( root == 0 ) root = new BSTNode<T>(el); else if( prev->data < el ) p = prev->rchild = new BSTNode<T>(el); else p = prev->lchild = new BSTNode<T>(el); } //find a place for inserting new node; //插入节点 插入节点
20
课堂练习
4.14 对于3个关键码值A、B、C,有多 少个不同的二叉搜索树?画出相应二叉 树。
21
平衡的二叉搜索树(AVL)
BST受输入顺序影响 受输入顺序影响
最好O(log n) 最好 最坏O(n) 最坏
怎样使得BST始终保持 始终保持O(log n)级的平衡状态? 级的平衡状态 怎样使得 始终保持 级的平衡状态? Adelson-Velskii和Landis发明了AVL树 发明了AVL Adelson-Velskii和Landis发明了AVL树
头歌二叉排序表的基本操作
头歌二叉排序表的基本操作一、概述二叉排序树,也称为二叉搜索树(Binary Search Tree, BST),是一种特殊的二叉树,其中每个节点都满足以下性质:对于任意节点,其左子树中所有节点的值都小于该节点的值,而其右子树中所有节点的值都大于该节点的值。
这种特性使得二叉排序树成为一种非常有效的数据结构,用于在各种算法中实现快速查找、插入和删除操作。
二、基本操作1. 插入操作插入操作是二叉排序树中最常用的操作之一。
其基本步骤如下:(1)创建一个新节点,并将要插入的值赋给该节点。
(2)如果二叉排序树为空,则将新节点作为根节点。
(3)否则,从根节点开始比较新节点的值与当前节点的值。
如果新节点的值小于当前节点的值,则将新节点插入到当前节点的左子树中;否则,将新节点插入到当前节点的右子树中。
(4)重复步骤3,直到找到一个空位置来插入新节点。
2. 删除操作删除操作是二叉排序树中比较复杂的操作之一。
其基本步骤如下:(1)找到要删除的节点。
如果找不到要删除的节点,则无法进行删除操作。
(2)如果找到要删除的节点,则将其从树中删除。
如果该节点只有一个子节点,则直接删除该节点;如果该节点有两个子节点,则可以选择将其中的一个子节点“提升”到该节点的位置,然后删除该子节点。
在提升子节点时,需要考虑子节点的值与要删除的节点的值之间的关系,以确保二叉排序树的性质不变。
(3)如果被提升的子节点仍然包含要删除的节点,则需要重复步骤2,直到找到要删除的节点并将其删除。
3. 查找操作查找操作用于在二叉排序树中查找指定的值。
其基本步骤如下:(1)从根节点开始,比较当前节点的值与要查找的值。
如果它们相等,则查找成功,返回当前节点的位置。
(2)如果当前节点的值大于要查找的值,则进入当前节点的左子树中进行查找;否则进入当前节点的右子树中进行查找。
(3)重复步骤2,直到找到要查找的值或者搜索路径上的所有节点都已访问过。
如果最终没有找到要查找的值,则返回空指针。
数据结构二叉排序树实验报告
*bst=s;
}
else if(key<(*bst)->key)
InsertBST(&((*bst)->lchild),key);//将s插入左子串
else if(key>(*bst)->key)
InsertBST(&((*bst)->rchild),key);//将s插入右子串
InsertBST(BSTree *bst,int key)
inorder(BSTree bt)
3、完整的程序:
#include"stdio.h"
#include"malloc.h"
typedef struct node
{
int key;//关键字的值
struct node *lchild,*rchild;//左右指针
}BSTNode,*BSTree;
元素类型为整形和指针形。
2、每个模块的分析:
(1)主程序模块:
main()
{
BSTree bt;
printf("please insert the numbers( 以0作为结束标志):\n");
CreateBST(&bt); /*构造排序二叉树*/
printf("\n中序遍历结果是:");
s->rchild=NULL;
*bst=s;
}
else if(key<(*bst)->key)
InsertBST(&((*bst)->lchild),key);//将s插入左子串
else if(key>(*bst)->key)
二叉排序树(二叉链表结构存储)数据结构课程设计报告
二叉排序树(二叉链表结构存储)数据结构课程设计报告目录1需求分析 (1)1.1课程设计题目、任务及要求 (1)1.2课程设计思想 (1)2概要设计 (2)2.1 二叉排序树的定义 (2)2.2二叉链表的存储结构 (2)2.3建立二叉排序树 (2)2.4二叉排序树的生成过程 (3)2.5中序遍历二叉树 (3)2.6二叉排序树的查找 (3)2.7二叉排序树的插入 (4)2.8平均查找长度 (4)3详细设计和实现 (4)3.1主要功能模块设计 (4)3.2主程序设计 (5)4调试与操作说明 (12)4.1程序调试 (12)4.2程序操作说明 (13)总结 (16)致谢 (17)参考文献 (19)1需求分析1.1课程设计题目、任务及要求二叉排序树。
用二叉链表作存储结构(1)以(0)为输入结束标志,输入数列L,生成一棵二叉排序树T;(2)对二叉排序树T作中序遍历,输出结果;(3)计算二叉排序树T查找成功的平均查找长度,输出结果;(4)输入元素x,查找二叉排序树T:若存在含x的结点,则删除该结点,并作中序遍历(执行操作2);否则输出信息“无x”;1.2课程设计思想建立二叉排序树采用边查找边插入的方式。
查找函数采用递归的方式进行查找。
如果查找成功则不应再插入原树,否则返回当前结点的上一个结点。
然后利用插入函数将该元素插入原树。
对二叉排序树进行中序遍历采用递归函数的方式。
在根结点不为空的情况下,先访问左子树,再访问根结点,最后访问右子树。
由于二叉排序树自身的性质,左子树小于根结点,而根结点小于右子树,所以中序遍历的结果是递增的。
计算二插排序树的平均查找长度时,仍采用类似中序遍历的递归方式,用s记录总查找长度,j记录每个结点的查找长度,s置初值为0,采用累加的方式最终得到总查找长度s。
平均查找长度就等于s/i(i为树中结点的总个数)。
删除结点函数,采用边查找边删除的方式。
如果没有查找到,则不对树做任何的修改;如果查找到结点,则分四种情况分别进行讨论:1、该结点左右子树均为空;2、该结点仅左子树为空;3、该结点仅右子树为空;4、该结点左右子树均不为空。
二叉排序书课程设计
二叉排序书课程设计一、课程目标知识目标:1. 让学生理解二叉排序树的概念、性质和基本操作,掌握二叉排序树的插入、删除和查找过程。
2. 使学生能够运用二叉排序树解决实际问题,如数据排序和查找。
技能目标:1. 培养学生运用二叉排序树进行数据组织和分析的能力。
2. 培养学生编写和调试二叉排序树相关程序的能力。
情感态度价值观目标:1. 培养学生对数据结构和算法的兴趣,激发学生学习主动性和积极性。
2. 培养学生勇于克服困难、独立解决问题的精神,增强团队合作意识。
3. 培养学生认识到二叉排序树在实际应用中的价值,提高对计算机科学的认识。
课程性质:本课程为计算机科学领域的数据结构与算法课程,以二叉排序树为主题,结合实际案例,使学生掌握二叉排序树的相关知识。
学生特点:学生已具备一定的编程基础和逻辑思维能力,但对二叉排序树的概念和操作尚不熟悉。
教学要求:1. 通过讲解、示例和练习,使学生掌握二叉排序树的基本原理和操作。
2. 注重理论与实践相结合,提高学生解决实际问题的能力。
3. 鼓励学生主动思考、提问,培养良好的学习习惯。
4. 强化编程实践,提高学生的编程技能和逻辑思维能力。
二、教学内容1. 引言:介绍二叉排序树的基本概念,及其在数据结构和算法中的应用。
- 相关章节:课本第X章“二叉树与二叉排序树”2. 二叉排序树的性质与定义:- 内容:二叉排序树的定义、性质、特点- 相关章节:课本第X章“二叉排序树的性质与定义”3. 二叉排序树的插入操作:- 内容:插入过程、算法实现、示例演示- 相关章节:课本第X章“二叉排序树的插入操作”4. 二叉排序树的删除操作:- 内容:删除过程、算法实现、示例演示- 相关章节:课本第X章“二叉排序树的删除操作”5. 二叉排序树的查找操作:- 内容:查找过程、算法实现、示例演示- 相关章节:课本第X章“二叉排序树的查找操作”6. 二叉排序树的应用实例:- 内容:实际案例、程序编写、问题解决- 相关章节:课本第X章“二叉排序树的应用”7. 二叉排序树的遍历:- 内容:遍历方法、算法实现、示例演示- 相关章节:课本第X章“二叉树的遍历”8. 总结与拓展:- 内容:二叉排序树的优缺点、拓展知识、高级话题- 相关章节:课本第X章“二叉排序树的总结与拓展”教学进度安排:1. 引言与基本概念(1课时)2. 二叉排序树的性质与定义(1课时)3. 插入与删除操作(2课时)4. 查找操作(1课时)5. 应用实例与程序编写(2课时)6. 遍历方法(1课时)7. 总结与拓展(1课时)三、教学方法1. 讲授法:- 通过对二叉排序树的基本概念、性质和操作进行系统讲解,使学生建立完整的知识体系。
二叉排序树例题
二叉排序树例题二叉排序树的例题二叉排序树(Binary Search Tree)又称二叉查找树或二叉搜索树,是一种特殊的二叉树结构。
在二叉排序树中,每个节点的值大于其左子树中任意节点的值,且小于其右子树中任意节点的值。
这种特性使得二叉排序树成为一种高效的数据结构,可用于解决许多实际问题。
下面将通过一个实例来演示如何构建和操作二叉排序树。
【例题】给定一组整数序列:8, 3, 10, 1, 6, 14, 4, 7, 13。
请按照以下步骤,构建一个二叉排序树。
Step 1: 创建根节点将第一个元素作为根节点,即:8。
此时二叉排序树如下所示:8Step 2: 插入节点依次将剩余的元素按照二叉排序树的规则插入到树中。
- 插入节点3:将3与根节点8比较,由于3小于8,故插入到8的左子树。
此时二叉排序树如下所示:83- 插入节点10:将10与根节点8比较,由于10大于8,故插入到8的右子树。
此时二叉排序树如下所示:8/ \3 10- 插入节点1:将1与根节点8比较,由于1小于8,故插入到3的左子树。
此时二叉排序树如下所示:8/ \3 10/1- 插入节点6:将6与根节点8比较,由于6小于8,故插入到3的右子树。
此时二叉排序树如下所示:/ \3 10/ \1 6- 插入节点14、4、7、13:依次按照二叉排序树的规则将14、4、7、13插入到对应的位置。
最终,构建完成的二叉排序树如下所示:8/ \3 10/ \ \1 6 14/ /4 13\7至此,我们通过插入一组整数序列,成功构建了一个二叉排序树。
二叉排序树的应用十分广泛,其中一个重要应用领域是快速查找。
由于二叉排序树具有严格的有序性,可以通过对树的遍历来快速查找所需元素。
例如,在上述构建的树中,我们可以通过以下步骤来查找节点6:Step 1: 比较根节点将6与根节点8比较,由于6小于8,故继续在左子树中查找。
Step 2: 比较子节点将6与左子节点3比较,由于6大于3,故继续在右子树中查找。
数据结构实验三——二叉树基本操作及运算实验报告
《数据结构与数据库》实验报告实验题目二叉树的基本操作及运算一、需要分析问题描述:实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目,以及二叉树常用运算。
问题分析:二叉树树型结构是一类重要的非线性数据结构,对它的熟练掌握是学习数据结构的基本要求。
由于二叉树的定义本身就是一种递归定义,所以二叉树的一些基本操作也可采用递归调用的方法。
处理本问题,我觉得应该:1、建立二叉树;2、通过递归方法来遍历(先序、中序和后序)二叉树;3、通过队列应用来实现对二叉树的层次遍历;4、借用递归方法对二叉树进行一些基本操作,如:求叶子数、树的深度宽度等;5、运用广义表对二叉树进行广义表形式的打印。
算法规定:输入形式:为了方便操作,规定二叉树的元素类型都为字符型,允许各种字符类型的输入,没有元素的结点以空格输入表示,并且本实验是以先序顺序输入的。
输出形式:通过先序、中序和后序遍历的方法对树的各字符型元素进行遍历打印,再以广义表形式进行打印。
对二叉树的一些运算结果以整型输出。
程序功能:实现对二叉树的先序、中序和后序遍历,层次遍历。
计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目。
对二叉树的某个元素进行查找,对二叉树的某个结点进行删除。
测试数据:输入一:ABC□□DE□G□□F□□□(以□表示空格),查找5,删除E预测结果:先序遍历ABCDEGF中序遍历CBEGDFA后序遍历CGEFDBA层次遍历ABCDEFG广义表打印A(B(C,D(E(,G),F)))叶子数3 深度5 宽度2 非空子孙数6 度为2的数目2 度为1的数目2查找5,成功,查找的元素为E删除E后,以广义表形式打印A(B(C,D(,F)))输入二:ABD□□EH□□□CF□G□□□(以□表示空格),查找10,删除B预测结果:先序遍历ABDEHCFG中序遍历DBHEAGFC后序遍历DHEBGFCA层次遍历ABCDEFHG广义表打印A(B(D,E(H)),C(F(,G)))叶子数3 深度4 宽度3 非空子孙数7 度为2的数目2 度为1的数目3查找10,失败。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
子树
parent=p;
//由于用覆盖法删根,则不必特殊考虑删根
p=p->right;
while(p->left)
{
parent=p;
p=p->left;
}
tmp->key=p->key;
if(p==parent->left)
parent->left=NULL;
else
parent->right=NULL;
KeyType key;
//存放节点的内容
} BSTNode, * BSTree; //声明二叉树的链表
BSTree insertBST(BSTree tptr,KeyType key)// 在二叉排序树中插入结点
{
//若二叉排序树 tptr 中没有关键字为 key 的结
点,则插入,否则直接返回
BSTree f,p=tptr; //p 的初值指向根结点 while(p) //查找插入位置,循环结束时,p 是空指针,f 指向待插入结点的双亲
**"<<endl;
cout<<"\t\t**
Q...... 结 束 对 这 棵 二 叉 树 的 操 作
**"<<endl;
cout<<"\t\t**
**"<<endl;
cout<<"\t\t***********************************************************"<<endl;
typedef struct BiTNode { // 结点结构
struct BiTNode *lchild, *rchild; } BiTNode, *BiTree;
// 左右孩子指针
二叉排序树插入算法伪代码如下:
1. 若 root 是空树,则将结点 s 作为根结点插入;否则 2. 若 s->data<root->data,则把结点 s 插入到 root 的左子树中;否则 3. 把结点 s 插入到 root 的右子树中。
武汉工程大学
计算机科学与工程学院
《数据结构》实验报告
专业班级 学生学号 学生姓名
09 计算机工程 01 0905080116 沈亮
实验地点 指导教师 实验时间
419 蔡琼
实验项目 实验类别
实
验
求
目 的
及
要
查找技术综合应用 操作性()验证性( )设计性( )综合性(Y )其它( )
(1)熟练掌握查找的常用算法; (2)熟练设计和应用查找算法解决比较简单的实际问题。
二叉排序树中删除一个结点 f 的左孩子结点 p 算法伪代码如下:
1. 若结点 p 是叶子,则直接删除结点 p; 2. 若结点 p 只有左子树,则只需重接 p 的左子树;
若结点 p 只有右子树,则只需重接 p 的右子树; 3. 若结点 p 的左右子树均不空,则
3.1 查找结点 p 的右子树上的最左下结点 s 以及结点 s 的双亲结点 par; 3.2 将结点 s 数据域替换到被删结点 p 的数据域; 3.3 若结点 p 的右孩子无左子树,则将 s 的右子树接到 par 的右子树上;
else if(tmp==parent->left)
parent->left=p;
else
parent->right=p;
free(tmp);
}
else if(!p->left) //的左子树为空,则重接 p 的左子树
{
p=p->right;
if(!parent) //要删根,须修改根指针
tptr=p;
break; parent=p; p=(key<p->key)?p->left:p->right; } if(!p) return NULL; tmp=p; if(!p->right&&!p->left) /*p 的左右子树都为空*/ { if(!parent) //要删根,须修改根指针
tptr=NULL; else if(p==parent->right)
BSTree p=root; if(p!=NULL){
inorder_btree(p->left ); cout<<" "<<p->key<<" "; inorder_btree(p->right ); } } int searchBST(BSTree t,KeyType key)//查找 { if(key==t->key) return 1; if(t==NULL) return 0; if(key<t->key) return searchBST(t->left,key); else return searchBST(t->right,key); } BSTree deleteBST(BSTree tptr,KeyType key)//删除 { BSTree p,tmp,parent=NULL; p=tptr; while(p) { if(p->key==key)
{ 建立 n 个关键字的二叉排序树; 从键盘输入调建立 n 个关键字依次用 InsertBST1(插入函数); 返回根结点 T;
数据结构上机实验
3
计算机科学与工程学院
输出过程; } 3)删除模块
DeleteNode(BiTree &T, int x) {
从二叉树排序树 T 中删除任意结点,其关键字为 x; 可以实现删除根结点、叶子结点以及其它任意结点的功能; } 4)插入模块 void InsertBST1(BiTree &T,BiTNode *s) { 在二叉树排序树 T 中,插入一个结点 s(递归算法); 被 CreatBST 函数调用; } 5)查找模块 BiTree searchBST1(BiTree T,TElemType key) { 在根指针 T 所指二叉排序树中递归查找关键字等于 key 的数据元素; 若成功,返回指向该数据元素结点的指针; 否则返回空指针; }
else if(tmp==parent->left)
parent->left=p;
else
parent->right=p;
free(tmp);
}
else if(p->right&&p->left) //p 有左子树和右子树,用 p 的后继覆盖 p 然后删去后继
{
//另有方法:用 p 的前驱覆盖 p 然后删去前驱||合并 p 的左右
类别 上机表现 报告质量 说明:
成绩评定表
评分标准
积极出勤、遵守纪律 认真完成实验任务 程序代码规范、功能正确 填写内容完整、体现收获
分值 30 分 70 分
得分
合计
评阅教师:
日 期:
年
月
日
计算机科学与工程学院
实验内容:二叉排序树。
任意给定一组数据,设计一个算法,建立一棵二叉排序树,对它进行查找、 插入、删除等操作。 实验说明: 二叉排序树存储结构如下:
do
{
flag=0;
cout<<"\n\n 中序遍历二叉树:"<<endl;
inorder_btree(root);
cout<<"\n"<<endl;
cout<<"\t\t************ 请 选 择 你 要 对 这 棵 二 叉 树 所 做 的 操
作:**************"<<endl;
free(p);
}
return tptr;
}
int main()
{
KeyType key;
int flag,test;
数据结构上机实验
7
计算机科学与工程学院
char cmd;
BSTree root;
do
{
cout<<"\n\n"<<endl;
cout<<"\t\t*******请选择你要执行的操作:********"<<endl;
是
否 结束
主要模块: 1)主函数模块 Main() { 建立 n 个关键字的二叉排序树并输出; 从二叉树排序树 T 中删除任意结点,其关键字为 key; 在二叉树排序树 T 中,插入一个结点 t,其关键字为 key; 在二叉排序树 T 中递归查找关键字等于 key2 的数据元素; } 2)创建二叉排序树模块 BiTree CreatBST(int n)
fflush(stdin);
cin>>cmd;
flag++;
}while(cmd!='c'&&cmd!='C'&&cmd!='a'&&cmd!='A');
if(cmd=='c'||cmd=='C')
{
cout<<"请输入你所要创建的二叉树的结点的值,以-1 结束:\n";
root=createBST();
parent->right=NULL; else
parent->left=NULL; free(p); }
数据结构上机实验
6
计算机科学与工程学院
else if(!p->right) //p 的右子树为空,则重接 p 的左子树