北邮数据结构实验—二叉排序树
数据结构二叉树实验报告

一 、实验目的和要求(1)掌握树的相关概念,包括树、节点的度、树的度、分支节点、叶子节点、孩子节点、双亲节 点、树的深度、森林等定义。
(2)掌握树的表示,包括树形表示法、文氏图表示法、凹入表示法和括号表示法等。
(3)掌握二叉树的概念,包括二叉树、满二叉树和完全二叉树的定义。
(4)掌握二叉树的性质。
(5)重点掌握二叉树的存储结构,包括二叉树顺序存储结构和链式存储结构。
(6)重点掌握二叉树的基本运算和各种遍历算法的实现。
(7)掌握线索二叉树的概念和相关算法的实现。
(8)掌握哈夫曼树的定义、哈夫曼树的构造过程和哈夫曼编码的产生方法。
(9)掌握并查集的相关概念和算法。
(10)灵活运用二叉树这种数据结构解决一些综合应用问题。
二、实验内容注:二叉树b 为如图7-123所示的一棵二叉树图7-123+实验7.1 编写一个程序algo7-1.cpp,实现二叉树的各种运算,并在此基础上设计一个程序exp7-1.cpp 完成如下功能:(1)输出二叉树b ;(2)输出H 节点的左、右孩子节点值; (3)输出二叉树b 的深度; (4)输出二叉树b 的宽度; (5)输出二叉树b 的节点个数;(6)输出二叉树b 的叶子节点个数。
实验7.2设计一个程序exp7-2.cpp,实现二叉树的先序遍历、中序遍历和后序遍历和非递归算法, 以及层次变量里的算法。
并对图7-123所示的二叉树b 给出求解结果。
b+ACF GIKL+NM+E+HdJD₄B臣1607-1.CPPif(b?-HULL)re3P4+;Qu[rear]-p-b;Qu[rear].1no=1;while(reart=front){Front++;b=Qu[front]-P;lnum-Qu[front].1no;if(b->Ichildt=NULL)rpar+t;Qu[rear]-p=b->1child;Qu[rear].Ino-lnun+1;if(D->rch11d?=NULL)1/根结点指针入队//根结点的层次编号为1 1/队列不为空1/队头出队1/左孩子入队1/右孩子入队redr+t;qu[rear]-p=b->rchild;Qu[rear].1no-lnun*1;}}nax-0;lnun-1;i-1;uhile(i<=rear){n=0;whdle(i<=rear ge Qu[1].1no==1num)n+t;it+;Inun-Qu[i].1n0;if(n>max)nax=n;}return max;田1607-1.CPPreturn max;}elsereturn o;口×int Modes(BTNode *D) //求二叉树D的结点个数int nun1,nun2;if(b==NULL)returng,else if(b->ichild==NULL&D->rchild==NULL)return 1;else{num1-Hodes(b->Ichild);num2=Nodes(b->rchild);return(num1+nun2+1);LeafNodes(BINode *D) //求二叉树p的叶子结点个数int num1,num2;1f(D==NULL)return 0;else if(b->1chi1d==NULLc& b->rch11d==NULL)return 1;else{num1-LeafModes(b->lchild);num2=LeafNodes(b->rchild);return(nun1+nun2);int程序执行结果如下:xCProrn FlslirosfViu l SudiollyPrjecslro7 LJebuglFoj7 ex<1)输出二叉树:A<B<D,E<H<J,K<L,M<,N>>>>),C<F,G<,I>>)<2)'H’结点:左孩子为J石孩子为K(3)二叉树b的深度:7<4)二叉树b的宽度:4(5)二叉树b的结点个数:14(6)二叉树b的叶子结点个数:6<?>释放二叉树bPress any key to continue实验7 . 2程序exp7-2.cpp设计如下:坠eTPT-2.EPP#include<stdio.h》winclude<malloc.h>deFn Masie 00typde chr ElemTyetypede sruct nde{ElemType data;stuc node *lclldstruct node rchild;》BTHode;extern vod reaeBNodeBTNode extrn void DispBTHode(BTNodeuoid ProrderBTNode *b)if(b?-NULL)- 回1 / 数据元素1 / 指向左孩子1 / 指向右孩子*eb car *str)xb1 / 先序遍历的递归算法1 / 访问根结点/ / 递归访问左子树1 7 递归访问右子树/ / 根结点入栈//栈不为空时循环/ / 退栈并访问该结点/ / 右孩子入栈{》v oidprintf(*c“,b->data); Preorder(b->lchild); Pre0rder(b->rchild);Preorder1(BTNode *b)BTNode xSt[Maxsize],*p;int top=-1;if(b!-HULL)top++;St[top]-b;uhle (op>-)p-St[top];top--;printf("%c“,p->data);if(p->rchild?-HULL)A约e程p7-2.CPPprintF(”后序逅历序列:\n");printf(" 递归算法=");Postorder(b);printf("\n");printf(“非递归算法:“);Postorder1(b);printf("\n");序执行结果如下:xCAPrograFleicsoftVisal SudlyrjecsProj 2Debuzlroj72ex"二叉树b:A(B(D,ECH<J,K(L,M<,N)>))),C(F,GC.I>))层次遍历序列:A B C D E F G H I J K L M N先序遍历序列:递归算法:A B D E H J K L M N C F G I非归算法:A B D E H J K L M N C F G I中序遍历序列:递归算法: D B J H L K M N E A F C G I非递归算法:D B J H L K M N E A F C G I后序遍历序列:递归算法: D J L N M K H E B F I G C A非递归算法:D J L N H K H E B F I G C APress any key to continue臼p7-3.CPP15Pp a t h[p a t h l e n]-b->d a t a;//将当前结点放入路径中p a t h l e n t+;/7路任长度培1Al1Path1(b->ichild,patn,pathlen);1/递归扫描左子树Al1Path1(b->rchild,path,pathlen); //递归扫描右子树pathlen-- ; //恢复环境uoid Longpath(BTNode *b,Elemtype path[1,int pathlen,Elemtype longpath[],int elongpatnien) int i;1f(b==NULL){if(pathlen>longpatnlen) //若当前路径更长,将路径保存在1ongpatn中for(i-pathlen-1;i>-8;i--)longpath[i]=path[1];longpathlen-pathlen;elsepath[pathlen]=b->data; pathlen4; //将当前结点放入路径中//路径长度增1iongPath(b->lchild,path₇pathlen,langpath,longpathien);//递归扫描左子树LongPath(b->rchiid,path,pathien,longpath,longpathien);//递归扫描石子树pathlen--; /7饮其环境oid DispLeaf(BTNode xb)- 口凶uoid DispLeaf(BTNode xb)iE(D!=NULL){ if(b->1child--HULL B& b->rchild--HULL)printf("3c“,b->data);elsepispLeaf(b->ichild);DispLeaf(b->rchild);oid nain()8TNodexb;ElenType patn[Maxsize],longpath[Maxsize];int i.longpathien-U;CreateBTNode(b,"A(B(D,E(H(J,K(L,H(,N))))),C(F,G(,I)))");printf("\n二灾树b:");DispBTNode(b);printf("\n\n*);printf(”b的叶子结点:");DispLeaf(b);printf("\n\n");printf("A11Path:");A11Path(b);printf("m");printf("AiiPath1:n");AliPath1(b.path.);printf("");LongPath(b,path,8,longpath,longpathlen);printf(”第一条量长路径长度=d\n”,longpathlen);printf(”"第一茶最长路径:");for(i=longpathlen;i>=0;i--)printf("c",longpatn[1]);printf("\n\n");。
数据结构试验报告 二叉排序树的操作

数据结构实验报告班级:信息与计算科学专业1102班学号: 1108060214姓名:朱晓东设计日期:2013.6.6西安科技大学计算机学院1.实验报告编写一个演示运用二叉排序树进行数据的的排序、插入、删除、查找等操作的程序。
2.需求分析本演示程序用vc6.0编写,完成数据的排序功能,同时能够进行数据的创建、插入、删除、查找。
(1)输入的形式和输入值的范围:创建二叉排序树时输入较多的值;插入元素时需要输入插入的元素的值;删除元素时输入元素的值;查找操作时需要输入元素的值。
所有输入中,元素的值都是整数。
(2)输出的形式:在创建、插入、删除的操作后,均显示操作后的元素的排序状况,有小到大排序。
(3)程序所能达到的功能:完成二叉排序树的生成、插入、删除、查找操作。
(4)测试数据:①插入操作中依次输入10 9 11 8 12 0(本程序是以0元素为为结束标志);②查找操作中输入13;③插入操作中输入13;3概要设计本程序包含8个函数:(1)主函数main()(2)创建二叉排序树函数BSTCreate(BiTree* bt)(3)显示操作菜单函数menu()(4)显示二叉排序树的内容函数BSTShow(BiTree bt)(5)插入元素函数BSTInsert(BiTree* bt,DataType key)(6)删除元素函数BSTDelete(BiTree* bt,DataType key)(7)查找元素函数BSTSearch(BiTree bt,DataType key)(8)查找要删除的元素的函数DeleteNode(BiTree* bt)各函数之间的关系如下:BSTCreate(BiTree* bt)menu()BSTShow(BiTree bt)mainBSTInsert(BiTree* bt,DataType key)BSTDelete(BiTree* bt,DataType key) DeleteNode(BiTree* bt)BSTSearch(BiTree bt,DataType key)4.详细设计实现概要设计中定义的所有数据类型,对每个操作给出伪码算法。
北邮数据结构实验报告

北邮数据结构实验报告北京邮电大学信息与通信工程学院2009级数据结构实验报告实验名称:实验三哈夫曼编/解码器的实现学生姓名:陈聪捷日期:2010年11月28日1.实验要求一、实验目的:了解哈夫曼树的思想和相关概念;二、实验内容:利用二叉树结构实现哈夫曼编/解码器1.初始化:能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立哈夫曼树。
2.建立编码表:利用已经建好的哈夫曼树进行编码,并将每个字符的编码输出。
3.编码:根据编码表对输入的字符串进行编码,并将编码后的字符串输出。
4.译码:利用已经建好的哈夫曼树对编码后的字符串进行译码,并输出译码结果。
5.打印:以直观的方式打印哈夫曼树。
6.计算输入的字符串编码前和编码后的长度,并进行分析,讨论哈夫曼编码的压缩效果。
7.用户界面可以设计成“菜单”方式,能进行交互,根据输入的字符串中每个字符出现的次数统计频度,对没有出现的字符一律不用编码。
2.程序分析2.1存储结构二叉树templateclassBiTree{public:BiTree();//构造函数,其前序序列由键盘输入~BiTree(void);//析构函数BiNode*Getroot();//获得指向根结点的指针protected:BiNode*root;//指向根结点的头指针};//声明类BiTree及定义结构BiNodeData:二叉树是由一个根结点和两棵互不相交的左右子树构成data:HCode*HCodeTable;//编码表inttSize;//编码表中的总字符数二叉树的节点结构templatestructBiNode//二叉树的结点结构{Tdata;//记录数据Tlchild;//左孩子Trchild;//右孩子Tparent;//双亲};编码表的节点结构structHCode{chardata;//编码表中的字符charcode[100];//该字符对应的编码};待编码字符串由键盘输入,输入时用链表存储,链表节点为structNode{charcharacter;//输入的字符unsignedintcount;//该字符的权值boolused;//建立树的时候该字符是否使用过Node*next;//保存下一个节点的地址};示意图:2.2关键算法分析1.初始化函数(voidHuffmanTree::Init(stringInput))算法伪代码:1.初始化链表的头结点2.获得输入字符串的第一个字符,并将其插入到链表尾部,n=1(n 记录的是链表中字符的个数)3.从字符串第2个字符开始,逐个取出字符串中的字符3.1将当前取出的字符与链表中已经存在的字符逐个比较,如果当前取出的字符与链表中已经存在的某个字符相同,则链表中该字符的权值加1。
数据结构 二叉排序树

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, 对关键字进行分析, 取随机性较好的两位十进制数作为哈希地址。
数据结构与算法—二叉排序树详解

数据结构与算法—二叉排序树详解前言前面介绍学习的大多是线性表相关的内容,把指针搞懂后其实也没有什么难度。
规则相对是简单的。
再数据结构中树、图才是数据结构标志性产物,(线性表大多都现成api可以使用),因为树的难度相比线性表大一些并且树的拓展性很强,你所知道的树、二叉树、二叉排序树,AVL树,线索二叉树、红黑树、B数、线段树等等高级数据结构。
然而二叉排序树是所有的基础,所以彻底搞懂二叉排序树也是非常重要的。
树参考王道数据结构二叉树也是树的一种,而二叉排序树又是二叉树的一种。
•树是递归的,将树的任何一个节点以及节点下的节点都能组合成一个新的树。
并且很多操作基于递归完成。
•根节点:最上面的那个节点(root),根节点没有前驱节点,只有子节点(0个或多个都可以)•层数:一般认为根节点是第1层(有的也说第0层)。
而树的高度就是层数最高(上图层数开始为1)节点的层数•节点关系:父节点:就是链接该节点的上一层节点,孩子节点:和父节点对应,上下关系。
而祖先节点是父节点的父节点(或者祖先)节点。
兄弟节点:拥有同一个父节点的节点们!•度:节点的度就是节点拥有孩子节点的个数(是孩子不是子孙).而树的度(最大)节点的度。
同时,如果度大于0就成为分支节点,度等于0就成为叶子节点(没有子孙)。
相关性质:•树的节点数=所有节点度数 1.•度为m的树第i层最多有mi-1个节点。
(i>=1)•高度而h的m叉树最多(mh-1)/(m-1)个节点(等比数列求和) •n个节点的m叉树最小高度[logm(n(m-1) 1)]二叉树二叉树是一树的一种,但应用比较多,所以需要深入学习。
二叉树的每个节点最多只有两个节点。
二叉树与度为2的树的区别:•一:度为2的的树必须有三个节点以上,二叉树可以为空。
•二:二叉树的度不一定为2:比如说斜树。
•三:二叉树有左右节点区分,而度为2的树没有左右节点的区分。
几种特殊二叉树:•满二叉树。
高度为n的满二叉树有2n-1个节点•完全二叉树:上面一层全部满,最下一层从左到右顺序排列•二叉排序树:树按照一定规则插入排序(本文详解)。
二叉排序树实验报告

深圳大学实验报告
课程名称:数据结构实验与课程设计
实验项目名称:二叉排序树实验
学院:计算机与软件学院
专业:
指导教师:
报告人:学号:班级: 3班
实验时间: 2012-11-28 实验报告提交时间: 2012-12-5
教务部制
int main(int argc,char *argv[])
{
int t[32];
int i,j,Key;
int TestNum,SampleNum;
// freopen("cin.txt","r",stdin);
// freopen("cout.txt","w",stdout);
BiSortTree *BST=new BiSortTree;
cin>>TestNum;
for(i=0;i<TestNum;i++){
cin>>SampleNum;
for(j=0;j<SampleNum;j++) cin>>t[j];
BST->CreateBST(t,SampleNum);
cin>>Key;
BST->SearchBST(Key);
cout<<BST->BisSuccess<<" "<<BST->BisPos <<" "<<BST->BisCount<<endl;
}
return 0;
}
运行截图:
2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。
数据结构二叉排序树
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
数据结构 二叉排序树[高级课件]
8
(2) 生成二叉排序树的算法:
BiTree crt_bstree(BiTree &root){
//输入一个关键字序列,生成一棵二叉排序树的二叉链表结构
root=NULL; read(x);
while (x≠ 结束标志){
s=(BiTree)malloc(sizeof(BiTNode))
s→key=x ; …… ; //生成新结点 s→lchild =NULL ; s→rchild =NULL; ins_ bstree(root, s); read(x);}
12
(3) 被删除的结点既有左子树,也有右子树
被删关键字 = 50 540
30
80
20
40 某结点的前驱一
定在它的左子树
90
的最右下方
35
85
32
前驱结点
88
被删结点
以其前驱替代之,然后 严选内容再删除该前驱结点 13
5. 二叉排序树的查找分析
比较次数 = 被查结点所在的层次数。 二叉排序树的性能取决于树的形态,而二叉树的 形态取决于插入结点的顺序。
9.4 二叉排序树
1.定义:
二叉排序树(二叉搜索树或二叉查找树) 或者是一棵空树;或者是具有如下特性的二叉树
(1) 若它的左子树不空,则左子树上所有结点的 值均小于根结点的值;
(2) 若它的右子树不空,则右子树上所有结点 的值均大于等于根结点的值;
(3) 它的左、右子树也都严分选内容别是二叉排序树。 1
struct BiTNode *lchild;
struct BiTNode *rchild;
} BiTNode,*BiTree;
严选内容
5
数据结构课程设计_二叉排序树的实现
数据结构课程设计一、引言数据结构是一门理论性强、思维抽象、难度较大的课程,是基础课和专业课之间的桥梁。
该课程的先行课程是计算机基础、程序设计语言、离散数学等,后续课程有操作系统、编译原理、数据库原理、软件工程等。
通过本门课程的学习,我们应该能透彻地理解各种数据对象的特点,学会数据的组织方法和实现方法,并进一步培养良好的程序设计能力和解决实际问题的能力。
数据结构是计算机科学与技术专业的一门核心专业基础课程,在该专业的课程体系中起着承上启下的作用,学好数据结构对于提高理论认知水平和实践能力有着极为重要的作用。
学习数据结构的最终目的是为了获得求解问题的能力。
对于现实世界中的问题,应该能从中抽象出一个适当的数学模型,该数学模型在计算机内部用相应的数据结构来表示,然后设计一个解此数学模型的算法,再进行编程调试,最后获得问题的解答。
实习课程是为了加强编程能力的培养,鼓励学生使用新兴的编程语言。
相信通过数据结构课程实践,无论是理论知识,还是实践动手能力,我们都会有不同程度上的提高。
二、课程设计目的本课程是数据结构课程的实践环节。
主要目的在于加强学生在课程中学习的相关算法和这些方法的具体应用,使学生进一步掌握在C++或其他语言中应用这些算法的能力。
通过课程设计题目的练习,强化学生对所学知识的掌握及对问题分析和任务定义的理解。
三、内容设计要求二叉排序树的实现:用顺序和二叉链表作存储结构1)以回车(‘\n’)为输入结束标志,输入数列L,生成一棵二叉排序树T;2)对二叉排序树T作中序遍历,输出结果;3)输入元素x,查找二叉排序树T,若存在含x的结点,则删除该结点,并作中序遍历(执行操作2);否则输出信息“无x”。
(一)问题分析和任务定义对问题的描述应避开具体的算法和涉及的数据结构,它是对要完成的任务作出明确的回答,强调的是做什么,而不是怎么做。
(二)详细的设计和编码算法的具体描述和代码的书写。
(三)上机调试源程序的输入和代码的调试。
数据结构-二叉排序树
0 3
-1
14 -1
28
+1
-1
18
50
0
0
17
30
60
0
0
53
63
是平衡树 2021/3/11 问:平衡树是理想平衡树吗? 不是平衡16树
如何检测二叉树是否失去平衡?
当插入一个新结点时,重新计算从新插入的 结点到根结点的路径上所包含结点的平衡因 子(bf),如果某一结点的 bf 的绝对值超 过1,则二叉树失去平衡。
特点:树结构在查找的过程中动态生成。 每次插入的结点只能成为新的叶子结点
例:关键字序列为 {45,24,53,12,14,90 }
45
24
53
2021/3/11
12 14
90
中序遍历:12,14,24,45,53,90 7
(1) 插入算法: status ins_bstree(BiTree &bt,BiTree s){
3)若给定值大于根结点的关键字,则
继续在右子树上进行查找。
2021/3/11
3
例如: 二叉排序树
50 30
20
40
80 90
35
85
32
88
查找关键字
= 50 , 35 , 90 , 95 ,
2021/3/11
4
二叉链表类型定义:
typedef struct BiTNode{
KeyType key;
// 将指针s所指的结点插入到根指针为bt的二叉排序树中
if (bt==NULL) bt = s ;
// 若bt为空树,则s为根
else if (s→key < bt→key) ins_bstree( bt→lchild ,s ); else ins_bstree( bt→rchild ,s);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告实验名称:______二叉排序树___________ 学生姓名:____________________班级:_______________班内序号:_______________________学号:________________日期:________________1.实验要求根据二叉排序树的抽象数据类型的定义,使用二叉链表实现一个二叉排序树。
二叉排序树的基本功能:1.二叉排序树的建立2.二叉排序树的查找3.二叉排序树的插入4.二叉排序树的删除5.二叉排序树的销毁6.其他:自定义操作编写测试main()函数测试二叉排序树的正确性2. 程序分析2.1 存储结构二叉链表2.2 程序流程(或程序结构、或类关系图等表明程序构成的内容,一般为流程图等)2.2.1.2.2.2.伪代码1.从文件读取待建树元素2.建树,若待插入元素比根节点小,向左子树前进并重复比较左子树根节点,若待插入元素比根节点大,向右子树前进并重复比较右子树根节点,直至找到空节点则插入该元素,不断插入直至不剩下元素。
3.用户选择操作。
4.若用户选择查找,则现由用户输入待查找数值。
从根节点开始比较,若较小则移至左子树,若较大则移至右子树,直至关键码相等,则输出节点情况。
5.若用户选择插入,则现由用户输入待插入数值。
从根节点开始比较,若较小则移至左子树,若较大则移至右子树,直至到空节点,则插入该元素。
6.若用户选择删除,则现由用户输入待删除数值。
从根节点开始比较,若较小则移至左子树,若较大则移至右子树,直至关键码相等;1).若该节点为叶子节点,则直接删除;2).若该节点无左子树,则其双亲节点直接与其右子树根节点连接,再删除该节点;3).若该节点有左子树,则其左子树的最右节点数值直接覆盖该节点数值,再删除最后节点。
7.若用户选择销毁,则不断执行删除操作直至不剩余节点。
8.若用户选择退出,则程序结束。
2.3 关键算法分析关键代码即删除操作,代码如下:void Delete(BiNode* &R){BiNode* q=new BiNode;BiNode *s=new BiNode;if(R->lch==NULL){q=R;R=R->rch;delete q;}else if(R->rch==NULL){q=R;R=R->lch;delete q;}else{q=R;s=R->lch;while(s->rch!=NULL){q=s;s=s->rch;}R->data=s->data;if(q!=R)q->rch=s->lch;elseR->lch=s->lch;delete s;}}void Deletedata(BiNode* &R, int key){if(R==NULL) return;if(R->data==key) Delete(R);else if(R->data>key) Deletedata(R->lch,key);else Deletedata(R->rch,key);}首先先要定位到要删除的节点,不断递归调用deletedata这个函数,找到数值与需要删除节点的数值相等的节点时,调用delete这个函数。
删除节点时需要分析三种情况。
1).若该节点为叶子节点,则直接删除;2).若该节点无左子树,则其双亲节点直接与其右子树根节点连接,再删除该节点;3).若该节点有左子树,则其左子树的最右节点数值直接覆盖该节点数值,再删除最后节点。
算法时间复杂度:O(n^2)2.4 其他特殊情况处理:若文件里元素为空,不存在任何元素,则无法完成建树,选择查找操作时也会提示无元素;另外,若查找不存在的元素是,最后查找到空节点也会提示无此元素。
3.程序运行结果分析4.总结4.1实验的难点和关键点本实验的难点和关键点主要在删除元素上,为了保持二叉排序树的有序性。
删除特定节点是要分三种情况讨论1).若该节点为叶子节点,则直接删除;2).若该节点无左子树,则其双亲节点直接与其右子树根节点连接,再删除该节点;3).若该节点有左子树,则其左子树的最右节点数值直接覆盖该节点数值,再删除最后节点。
4.2心得体会通过这次试验让我进一步对树的应用有了进一步的了解,同时对查找这种基本数据操作有了较深刻的认识.同时在二叉排序树的删除操作的代码编写时,让我明白了不同情况的不同处理方式。
养成了更严谨的编写代码的思维方式。
附:程序代码#include<iostream>#include<fstream>using namespace std;class BiNode{public:int data;BiNode* lch;BiNode* rch;BiNode():lch(NULL),rch(NULL){};};BiNode* Search(BiNode* R,int key){ if(R==NULL) {cout<<"无查询结果"<<endl;return NULL;}if(R->data==key) return R;if(R->data<key) return Search(R->rch,key);if(R->data>key) return Search(R->lch,key);}void Insert(BiNode* &R,BiNode* S){if(R==NULL) R=S;if(R->data<S->data) Insert(R->rch,S);if(R->data>S->data) Insert(R->lch,S);}BiNode* Create(int data[],int n){BiNode* R=new BiNode;R=NULL;for(int i=0;i<n;i++){BiNode* Q=new BiNode;Q->data=data[i];Insert(R,Q);}return R;}void Delete(BiNode* &R){BiNode* q=new BiNode;BiNode *s=new BiNode;if(R->lch==NULL){q=R;R=R->rch;delete q;}else if(R->rch==NULL){q=R;R=R->lch;delete q;}else{q=R;s=R->lch;while(s->rch!=NULL){q=s;s=s->rch;}R->data=s->data;if(q!=R)q->rch=s->lch;elseR->lch=s->lch;delete s;}}void Deletedata(BiNode* &R, int key){if(R==NULL) return;if(R->data==key) Delete(R);else if(R->data>key) Deletedata(R->lch,key);else Deletedata(R->rch,key);}void Deleteall(BiNode* &R,int data[],int n){for(int i=0;i<n;i++){Deletedata(R,data[i]);}}void main(){int data[200];BiNode *Root;Root=NULL;ifstream ifile("D://TEST//data.txt");int i=0,n=0;cout<<"从文件读入数据如下:"<<endl;while(ifile>>data[i]){cout<<data[i]<<" ";i++;n++;}Root=Create(data,n);while(1){cout<<"\n请输入进行的操作:\n1.查找\n2.插入\n3.删除\n4.销毁\n5.退出\n"; int choice;cin>>choice;while(choice!=1&&choice!=2&&choice!=3&&choice!=4&&choice!=5){ cout<<"无该选项,请重新输入";cin>>choice;}switch(choice){case 1:{cout<<"请输入查找的数据"<<endl;int n;int i;cin>>n;BiNode* R;R=Search(Root,n);if(R->lch!=NULL){cout<<"该数据节点左孩子数据为"<<R->lch->data<<endl;}if(R->rch!=NULL){cout<<"该数据节点右孩子数据为"<<R->rch->data<<endl;}if(R->lch==NULL&&R->rch==NULL){cout<<"该数据节点为叶子节点";}break;}case 2:{cout<<"请输入插入数据"<<endl;int t;cin>>t;BiNode* w=new BiNode;w->data=t;Insert(Root,w);cout<<"插入成功"<<endl;cout<<"目前关键码为:";for(int i=0;i<n;i++){cout<<data[i]<<" ";}cout<<t<<" "<<endl;break;}case 3:{int k;cout<<"请输入删除数据"<<endl;int s,judge=1;cin>>s;for(k=0;k<n;k++){if(data[k]==s)break;}if(k==n){cout<<"该数据不存在"<<endl;}else {Deletedata(Root,s);cout<<"删除成功";}cout<<"剩余关键码为:";for(int q=0;q<n;q++){if(q==k) q++;cout<<data[q]<<" ";}break;}case 4: Deleteall(Root,data,n);break;case 5: return;}}system("pause");}。