杭电软件技术基础实验报告Word文档格式.docx
- 文档编号:16777045
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:28
- 大小:271.97KB
杭电软件技术基础实验报告Word文档格式.docx
《杭电软件技术基础实验报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《杭电软件技术基础实验报告Word文档格式.docx(28页珍藏版)》请在冰豆网上搜索。
,&
DataCount);
请输入Maxdata:
Maxdata);
if(DataCount>
=10&
&
DataCount<
=20&
Maxdata>
=50&
Maxdata<
=100)break;
printf("
输入不正确,请重新输入!
\n"
fflush(stdin);
//清空输入
}
2.在0和MaxData之间,随机产生DataCount个不重复的整数,按产生先后顺序形成一个数据序列,并输出该序列。
因为输入的DataCount具有随机性,数组的长度无法确定,因此想到要申请分配动态数组。
这里需要在0和MaxData之间,随机产生DataCount个不重复的整数,使用c语言中的rand语句,生成一组随机数,并赋值给数组。
要保证不重复,引入下表j,若两数相等,则i自减,继续产生数据。
if((arr=(int*)malloc(DataCount*sizeof(int)))==NULL)//申请动态数组
{
分配内存空间失败,程序退出!
return0;
for(i=0;
i<
DataCount;
i++)//向申请成功的数组中赋值
arr[i]=rand()%(Maxdata+1);
for(j=0;
j<
i;
j++)//保证随机数不重复
if(arr[i]==arr[j])
i--;
}
输出不重复的数据序列:
\n"
i++)//输出不重复的数据序列
%d\t"
arr[i]);
3.利用上述数据序列,创建一个二叉排序树。
首先需要定义节点数据结构,然后根据二叉排序树的特点(左子树节点值小于根节点值,右子树节点值大于等于根节点值),定义插入二叉排序树的insertTree函数,最后定义Creatree函数,并在其中调用insertTree函数,实现了二叉排序树的创建。
voidinsertTree(Tnode**r,intdata){//插入二叉排序树
if(*r==NULL){//如果树为空,则建树
*r=(Tnode*)malloc(sizeof(Tnode));
(*r)->
data=data;
lchild=NULL;
rchild=NULL;
elseif(data<
(*r)->
data)//当前值小于根结点,建左子树
insertTree(&
((*r)->
lchild),data);
elseif(data>
data)//当前值大于根结点,建右子树
rchild),data);
}
voidCreatree(Tnode**r,inta[],intn){//调用插入函数,实现二叉排序树的创建
inti;
n;
i++)
(*r),a[i]);
4.设计函数,统计该二叉树的高度。
二叉树的高度为二叉树中节点层次的最大值,因此需要分别遍历左、右子树,并求高度。
二叉树的高度为左子树高度、右子树高度中较大的那个。
intGetHeight(Tnode*r){//定义统计二叉树的高度的函数
inthl,hr,max;
if(r!
=NULL){
hl=GetHeight(r->
lchild);
//求左子树高度
hr=GetHeight(r->
rchild);
//求右子树高度
max=hl>
hr?
hl:
hr;
return(max+1);
}
elsereturn0;
5.设计函数,输出该二叉树的叶子节点。
当节点的左右子树同时为空时,即为叶子结点。
对二叉树进行遍历,判断被访问的节点是否为叶子节点,若是,将叶子节点对应的数值输出。
if(r==0)return;
elseif(r->
lchild==NULL&
r->
rchild==NULL)//节点的左右子树同时为空,即为叶子
%d"
r->
data);
outleaf(r->
lchild);
rchild);
6.设计中序遍历函数,遍历该二叉排序树,输出遍历序列,验证创建的二叉排序树是否正确。
首先按中序遍历的顺序递归左子树,然后访问根节点,最后按中序遍历的顺序递归遍历右子树,即可设计中序遍历函数。
由于二叉排序树的中序遍历结果应为从小到大排序,所以只需观察中序遍历序列,即可验证正确性。
voidinorder(Tnode*r){//定义实现中序遍历的函数
if(r){
inorder(r->
printf("
三.算法流程图
根据上述功能的分析,设计出本实验的算法流程图如下所示:
图1算法流程图
四.程序源代码
#include<
stdio.h>
stdlib.h>
time.h>
typedefstructnode{//节点数据类型
intdata;
structnode*lchild,*rchild;
}Tnode;
//求左子树高度
//求右子树高度
voidoutleaf(Tnode*r){//定义输出二叉树的叶子节点的函数
if(r==0)return;
elseif(r->
}
intmain()
srand(time(NULL));
Tnode*r=NULL;
intDataCount,Maxdata,i,j;
int*arr;
while
(1)//死循环,不得到正确输入不退出
//清空输入
i++){//向申请成功的数组中赋值
j++)//保证随机数不重复
Creatree(&
r,arr,i);
输出二叉树的高度:
%d\n"
GetHeight(r));
//输出二叉树的高度
输出二叉树的叶子节点:
outleaf(r);
//输出二叉树的叶子节点
输出中序遍历序列:
inorder(r);
//输出中序遍历序列
free(arr);
//使用完后要释放所申请的空间
五.调试方法和调试过程
调试过程中,出现了大大小小的问题:
第一次编译,很多错误,仔细检查后发现是头文件缺失造成的。
修改后,错误明显少多了。
还有语句后面忘记加分号或者中英文没有区分,导致了一些编译错误。
耐心的调试后,所有的错误都解决了。
六.程序运行主要截图
1.输入DataCount和MaxData,若输入的两个值再指定的范围内(即
),则程序向下执行;
若不再指定范围内,则提示重新输入。
运行窗口如下:
图2输入正确的数值
2.创建二叉树,输出高度、叶子节点,对二叉排序树进行中序遍历。
图3高度、叶子节点、中序遍历
七.总结与体会
这次上机练习,感受之一就是手生,好长时间不用c语言编程,有一种陌生感,所以这次练习调试程序过程中也遇到了大大小小的困难,不过通过自己网上查找资料都解决了。
对一些c语言编程用法加深了理解,比如动态分配数组,生成随机数,结构体,递归等内容,现在能够熟练应用,并在实际问题中实现。
其次,深刻认识了二叉排序树的结构,运用递归定义函数实现了二叉树的构建,求解树的高度、叶子节点等内容,有关二叉树的三种遍历方法也清楚了具体的遍历顺序。
实验二:
链式二叉排序树的查找和删除
1.加深理解数据结构的目的和概念,以及逻辑结构和物理结构的关系;
2.锻炼较为复杂数据结构算法的设计和编程实现;
3.练习链表的程序设计,掌握二叉链表的设计技术;
4.熟悉图结构的物理存储和应用的编程方法;
5.熟悉软件功能的分析设计方法和测试方法。
1.创建一棵二叉排序树(以下称为源二叉树)。
创建方法与实验一相同,这里不做叙述。
2.从源二叉树拷贝一个二叉树(以下称为二叉树副本)。
首先判断二叉树是否为空,若二叉数为空,则没有任何操作;
若二叉树不为空,开辟内存空间,依次复制根节点,左子树和右子树,至此完成二叉树的复制。
Tnode*mycopy(Tnode*r){//二叉树的复制
if(!
r)returnNULL;
Tnode*copyr=(Tnode*)malloc(sizeof(Tnode));
copyr->
data=r->
data;
lchild=mycopy(r->
rchild=mycopy(r->
returncopyr;
};
3.通过键盘输入数据,指定查找的目标二叉树(源二叉树和二叉树副本),在目标二叉树中查找是否存在该数据,若存在,则输出提示以及该数据节点的地址,若不存在,则输出提示。
首先,通过定义变量k,选择查找哪一棵树。
k=1,表明在源二叉树中查找;
k=2,表明在二叉树副本中查找;
k=其他值,提示“选择错误”,并且重新输入,直到查找的二叉树为源二叉树或副本。
因为需要在目标二叉树中查找是否存在某数据,所以要定义一个查找节点的函数。
这里编写了search函数,首先判断根节点数值与要查找数值是否相等,若等,则输出找到;
若不等,则对左子树、右子树递归调用上面函数。
Tnode*search(Tnode*r,intkey){//在二叉排序树中查找值为key的节点
if(r==NULL)
{
printf("
没有找到!
returnNULL;
elseif(r!
=NULL&
key==r->
data){
Findit!
输出数据在内存中的地址:
r);
returnr;
elseif(key<
data)
returnsearch(r->
lchild,key);
elseif(key>
rchild,key);
4.删除数据操作:
通过键盘输入数据;
如果二叉树副本中存在该数据,则从二叉树副本中删除该数据节点,输出提示,并输出源二叉树和删除操作后的二叉树副本的中序遍历结果和高度;
如果二叉树副本中不存在该数据,输出提示,并输出提示源二叉树中是否存在该数据节点以及节点地址。
对二叉树的节点进行删除操作,要分下面三种情况:
1)当删除的节点是叶子节点时,只要把删除节点的父节点对应的指针指向NULL即可,然后释放掉删除节点的空间。
2)当删除的节点只有一个子节点(左子树或右子树),把删除节点的父节点中对应的指针指向删除节点的子节点即可。
然后释放掉删除节点的空间;
3)当删除的节点左右子树都有,这种情况下,必须要找到一个替代删除节点的替代节点,并且保证二叉树的排序性。
根据二叉树的排序性,可知替代节点的键值必须最接近删除节点键值。
比删除节点键值小的所有键值中最大那个,或者是比删除节点键值大的所有键值中最小的那个,是符合要求的。
这两个键值所在的节点分别在删除节点的左子树中最右边的节点,删除节点右子树中最左边的节点;
//获得其父节点
Tnode*getFather(Tnode*r,Tnode*s)
{
Tnode*sf;
if(r==NULL||r==s)
sf=NULL;
else{
if(s==r->
lchild||s==r->
rchild)
sf=r;
elseif(s->
data>
r->
data)
sf=getFather(r->
rchild,s);
else
lchild,s);
}
returnsf;
//二叉树删除
voidDeleteNode(Tnode*r,intkey)
Tnode*L,*LL;
//在删除左右子树都有的结点时使用;
Tnode*p=r;
Tnode*parent=r;
intchild=0;
//0表示左子树,1表示右子树;
r)//如果排序树为空,则退出;
return;
while(p)//二叉排序树有效;
if(p->
data==key)
if(!
p->
lchild&
!
rchild)//叶结点(左右子树都为空);
{
if(p==r)//被删除的结点只有根结点;
free(p);
elseif(child==0)
{
parent->
//设置父结点左子树为空;
//释放结点空间;
}
else//父结点为右子树;
parent->
//设置父结点右子树为空;
}
elseif(!
lchild)//左子树为空,右子树不为空;
if(child==0)//是父结点的左子树;
lchild=p->
rchild;
else//是父结点的右子树;
rchild=p->
free(p);
//释放被删除的结点;
rchild)//右子树为空,左子树不为空;
lchild;
else
LL=p;
//保存左子树的结点;
L=p->
//从当前结点的右子树进行查找;
if(L->
lchild)//左子树不为空;
LL=L;
L=L->
//查找左子树;
p->
data=L->
//将左子树的数据保存到被删除结点;
LL->
lchild=L->
//设置父结点的左子树指针为空;
for(;
L->
L=L->
L->
else
rchild=L->
p=NULL;
elseif(key<
data)//需删除记录的关键字小于结点的数据;
{//要删除的结点p是parent的左子树;
child=0;
//标记在当前结点左子树;
parent=p;
//保存当前结点作为父结点;
p=p->
else//需删除记录的关键字大于结点的数据;
{//要删除的结点p是parent的右子树;
child=1;
//标记在当前结点右子树查找;
//保存当前结点作为父结点;
//查找右子树;
5.将源二叉树视为一个图数据结构,编写函数实现该图的邻接表存储(注意程序需确保该操作不会被重复操作)。
首先对每个顶点
建立一个单链表,这个单链表由邻接于
的所有顶点构成。
这个表头节点通常以顺序存储结构存储,以便随机访问任一顶点的链表。
6.编写函数实现该图的拓扑排序,并输出拓扑序列。
首先在有向图中选取一个没有前驱的顶点(即入度为0的顶点),并输出该顶点;
然后从有向图中删除该顶点和以它为尾的所有弧;
重复前两步,直到全部顶点都被输出,或者有向图中没有入度为0的顶点为止。
voidTopoSort(adjlistGL,intn)
inti,j,k,top,m=0;
/*m用来统计拓扑序列中的顶点数*/
structedgenode*p;
/*单链表*/
int*d=(int*)malloc(n*sizeof(int));
/*定义存储图中每个顶点入度的一维整形数组d*/
d[i]=0;
/*初始化数组*/
i++)/*利用数组d中的对应元素统计出图中每个顶点的入度*/
p=GL[i];
while(p!
=NULL)
j=p->
adjvex;
d[j]++;
p=p->
next;
top=-1;
/*初始化用于链接入度为0的元素的栈的栈顶指针为-1*/
i++)/*建立初始化栈*/
if(d[i]==0)
d[i]=top;
top=i;
while(top!
=-1)/*每循
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件技术 基础 实验 报告