神奇的酒杯课程设计报告书.docx

上传人:b****5 文档编号:7893896 上传时间:2023-01-27 格式:DOCX 页数:16 大小:147.41KB
下载 相关 举报
神奇的酒杯课程设计报告书.docx_第1页
第1页 / 共16页
神奇的酒杯课程设计报告书.docx_第2页
第2页 / 共16页
神奇的酒杯课程设计报告书.docx_第3页
第3页 / 共16页
神奇的酒杯课程设计报告书.docx_第4页
第4页 / 共16页
神奇的酒杯课程设计报告书.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

神奇的酒杯课程设计报告书.docx

《神奇的酒杯课程设计报告书.docx》由会员分享,可在线阅读,更多相关《神奇的酒杯课程设计报告书.docx(16页珍藏版)》请在冰豆网上搜索。

神奇的酒杯课程设计报告书.docx

神奇的酒杯课程设计报告书

一、题目:

(神奇的酒杯)小L在一次登山游玩不小心掉到了山底下摔断了右脚,然而庆幸的是竟让他发现了一个神奇的酒杯。

小L拿过酒杯摸一摸召唤出了酒杯里的大神,他求大神解救他的右脚。

但是大神就是大神,哪能随便施法呢,大神说:

你要是能解答我一个问题,我就搭救你。

问题是这样的:

已知有一棵树根为1,树上有N个结点编号为1~N,每个结点上有一个权值,大神可以随时改变某个结点的权值,他想求的是某棵子树上结点权值的最大值。

小L是个菜鸟,只恨算法没学好啊,只好把问题交给你了。

要求:

(1)输入第一行一个正整数N(2

多组数据,N=0结束。

第二行为N个数,分别表示1~N的结点上的权值[1,100000000]接下来的N-1行,每行包含两个数u,v,表示u,v之间有一条边。

第N+2行输入为正整数M(0<=M<=100000)。

下面的M行输入为“C x y”或“Q x”。

(x为1到N的数)。

“C x y”表示将结点x的值改变成y(y>0)。

“Q x” 表示查询以x为根的子树上结点的权值的最大值。

(2)输出:

对每个查询输出相应的最大值。

(3)所设计的数据结构应尽可能节省存储空间。

(4)程序的运行时间应尽可能少。

二、问题分析:

此程序需要完成如下要求:

已知有一棵树根为1,树上有N个结点编号为1~N,每个结点上有一个权值,大神可以随时改变某个结点的权值,他想求的是某棵子树上结点权值的最大值。

实现本程序需要解决以下几个问题:

1、应该选择怎样的存储结构。

2、如何通过给定的二叉树的边信息,建立二叉树。

3、如何将结点x的权值改变成y。

4、怎样查询以x为根的子树上结点的权值的最大值。

5、怎样确定所需要的操作是改变权值还是查询权值的最大值。

输入要求:

输入第一行一个正整数N(2

多组数据,N=0结束。

第二行为N个数,分别表示1~N的结点上的权值[1,100000000]接下来的N-1行,每行包含两个数u,v,表示u,v之间有一条边。

第N+2行输入为正整数M(0<=M<=100000)。

下面的M行输入为“C x y”或“Q x”。

(x为1到N的数)。

“C x y”表示将结点x的值改变成y(y>0)。

“Q x” 表示查询以x为根的子树上结点的权值的最大值。

输出要求:

对每个查询输出相应的最大值。

三、数据结构的选择和概要设计:

数据结构的选择

根据题目要求,存储结构既要保存二叉树边所连接的两个端点,又要保存二叉树中结点的权值。

所以,在这里我选择了静态链表的存储结构。

链表结点的地址表示二叉树结点的序号,链表结点中的data域表示二叉树结点的权值。

存储结构模型如下图:

1

lchild

data

rchild

2

lchild

data

rchild

.

lchild

data

rchild

n

lchild

data

rchild

概要设计:

1、如何通过给定的二叉树的边信息,建立二叉树。

在输入时,二叉树的边的信息用这条边所连接的两个端点的序号(a,b)表示。

在建立二叉树的函数中,将结点b的地址赋值给结点a的孩子结点指针域。

2、如何将结点x的权值改变成y。

对于将结点x中的权值改变为y这个操作非常简单,可以直接将结点x中的data域赋值为y即可。

3、怎样查询以x为根的子树上结点的权值的最大值。

对于这个问题,可以采用遍历的方法,并找出最大值。

当要查询以x为根的子树上结点的权值时,将结点x的地址作为参数输入到遍历函数中,调用先序递归遍历函数。

并设置一个全局的静态变量max,用来找出子树中权值的最大值。

设max初始值为0,遍历子树中的权值。

当max小于这个结点的权值时,将max的值赋值为该结点的权值;当max不小于这个结点的权值时,不做任何操作。

4、怎样确定所需要的操作是改变权值还是查询权值的最大值。

对于这个问题,可以设置一个菜单选项。

根据输入决定将要做的操作。

程序包含的函数有:

主函数:

main();

建二叉树函数:

bitree*creatree();

改变指定结点的权值函数:

bitree*change_bt(intx,inty);

查询以x为根的子树上结点的权值的最大值函数:

voidpreorder(bitree*t);

程序的流程图如下:

(c)(q)

(t)

 

 

4、算法思想:

此程序中最主要的问题就是,如何建立二叉树和查询以x为根的子树上结点的权值的最大值。

建二叉树的算法思想:

按提示输入二叉树的结点个数,接着再按提示输入二叉树的结点权值。

此程序的核心在于,当输入边的信息时,建立二叉树。

在这,我的算法思想是,当输入的边的信息是(a,b)时,首先检查结点a的左孩子的指针域是否为空,若为空,则将a的左孩子的指针域赋值为结点b的地址。

操作如下:

for(i=0;i

{

scanf("%d%d",&a,&b);

if(bt[a-1].lchild==NULL)

bt[a-1].lchild=&bt[b-1];

else

bt[a-1].rchild=&bt[b-1];

}

查询以x为根的子树上结点的权值的最大值的算法思想:

对于这个问题,采用遍历的方法,并找出最大值。

当要查询以x为根的子树上结点的权值时,将结点x的地址作为参数输入到遍历函数中,调用先序递归遍历函数。

并设置一个全局的静态变量max,用来找出子树中权值的最大值。

设max初始值为0,遍历子树中的权值。

当max小于这个结点的权值时,将max的值赋值为该结点的权值;当max不小于这个结点的权值时,不做任何操作。

操作如下:

t=&bt[x-1];

if(t)

{

if(maxdata)

max=t->data;

preorder(t->lchild);

preorder(t->rchild);

}

5、详细设计和主要代码段:

1、存储结构的确定:

根据题目要求,存储结构既要保存二叉树边所连接的两个端点,又要保存二叉树中结点的权值。

所以,在这里我选择了静态链表的存储结构。

设计如下:

typedefstructnode

{

intdata;

node*lchild,*rchild;

}bitree;

2、首先需要解决的问题是如何按照题目的要求建立二叉树:

按提示输入二叉树的结点个数,接着再按提示输入二叉树的结点权值。

此程序的核心在于,当输入边的信息时,建立二叉树。

在这,我的设计是,当输入的边的信息是(a,b)时,首先检查结点a的左孩子的指针域是否为空,若为空,则将a的左孩子的指针域赋值为结点b的地址。

详细设计流程图如下:

for(i=0;i

{scanf("%d",&bt[i].data);}

(a,b)

 

YN

 

 

源代码如下:

bitree*creatree()

{

inti,a,b;

printf("输入二叉树的结点个数!

\n");

scanf("%d",&n);

printf("输入结点的权值(%d个)!

\n",n);

for(i=0;i

{

scanf("%d",&bt[i].data);

bt[i].lchild=bt[i].rchild=NULL;

}

printf("输入二叉树边的关系(%d个)!

\n",(n-1));

for(i=0;i

{

scanf("%d%d",&a,&b);

if(bt[a-1].lchild==NULL)

bt[a-1].lchild=&bt[b-1];

else

bt[a-1].rchild=&bt[b-1];

}

returnbt;

}

3、改变指定结点的权值函数:

对于将结点x中的权值改变为y这个操作非常简单,可以直接将结点x中的data域赋值为y即可。

源代码如下:

bitree*change_bt(intx,inty)

{

bt[x-1].data=y;

returnbt;

}

4、查询以x为根的子树上结点的权值的最大值函数:

对于这个问题,采用遍历的方法,并找出最大值。

当要查询以x为根的子树上结点的权值时,将结点x的地址作为参数输入到遍历函数中,调用先序递归遍历函数。

并设置一个全局的静态变量max,用来找出子树中权值的最大值。

设max初始值为0,遍历子树中的权值。

当max小于这个结点的权值时,将max的值赋值为该结点的权值;当max不小于这个结点的权值时,不做任何操作。

YN

 

并且递归调用函数。

源代码如下:

voidpreorder(bitree*t)

{

if(t)

{

if(maxdata)

max=t->data;

preorder(t->lchild);

preorder(t->rchild);

}

}

6、上机调试情况记录

1、语法错误及其修改:

出现的语法问题主要在于子函数和变量的定义,括号的配对,关键字和函数名称的书写,和一些库函数的规范使用。

这些问题均可以根据编译器的警告提示,对应的将其解决。

2、逻辑问题的修改和调整:

在递归调用preorder(bitree*t)函数时,max没有设置为静态变量。

使得程序每次递归调用时都被初始化为0,使得程序实现不了查询以x为根的子树上结点的权值的最大值的功能。

后来将max修改为全局静态变量后,程序每次递归调用函数时,max不会再次被初始化,使得程序实现了查询以x为根的子树上结点的权值的最大值功能。

3、空间性能的调整:

在preorder(bitree*t)函数中,一开始使用的是,先定义了一个全局数组Z_C[m],存储遍历时的data域的值,然后再在Z_C[m]数组中找出最大的权值。

后来考虑到这样浪费了m个int型的存储空间。

决定使用一个静态变量max。

设max初始值为0,遍历子树中的权值。

当max小于这个结点的权值时,将max的值赋值为该结点的权值;当max不小于这个结点的权值时,不做任何操作。

7、测试用例、结果及其算法性能分析

当输入的数据为:

结点数为3

权值为231645

边的信息为:

12

13

操作为:

Q2

Q3

C234

Q2

当输入的数据为:

结点数为6

权值为2316456356

边的信息为:

12

23

24

45

46

操作为:

Q5

Q3

C512

Q2

当输入的数据为:

结点数为3

权值为231645

边的信息为:

12

23

操作为:

Q2

Q3

C234

Q2

算法性能分析:

1、时间性能:

本程序的时间性能较好。

所有函数中仅有一层for循环,没有任何嵌套循环,所以本程序的时间性能为O(n)。

2、空间性能:

解决本问题,采用的是静态链表,所以空间性能为O(n)。

除此以外,还定义了全局变量n,用来存放结点的个数;还有,定义了一个全局静态变量max。

所以此程序的空间性能还是O(n)。

八、用户使用说明

本程序在运行过程中带有提示性语句。

由于本程序需要输入的数据比较多,输入时要按照提示进行,如果输入错误,提示输入错误并不录入。

所以,在运行时,只要按照提示输入就行了。

9、参考文献

[1]王昆仑,李红.数据结构与算法.北京:

中国铁道出版社,2006年5月。

[2]李红,王昆仑."数据结构与算法"实验指导合肥:

合肥学院教务处2006年5月。

10、附录(完整源程序)

#include

#definem20

staticintmax=0;

intn;

typedefstructnode

{

intdata;

node*lchild,*rchild;

}bitree;

bitreebt[m];

bitree*creatree()

{

inti,a,b;

printf("输入二叉树的结点个数!

\n");

scanf("%d",&n);

printf("输入结点的权值(%d个)!

\n",n);

for(i=0;i

{

scanf("%d",&bt[i].data);

bt[i].lchild=bt[i].rchild=NULL;

}

printf("输入二叉树边的关系(%d个)!

\n",(n-1));

for(i=0;i

{

scanf("%d%d",&a,&b);

if(bt[a-1].lchild==NULL)

bt[a-1].lchild=&bt[b-1];

else

bt[a-1].rchild=&bt[b-1];

}

returnbt;

}

bitree*change_bt(intx,inty)

{

bt[x-1].data=y;

returnbt;

}

voidpreorder(bitree*t)

{

if(t)

{

if(maxdata)

max=t->data;

preorder(t->lchild);

preorder(t->rchild);

}

}

voidmain()

{

inta,b,n;

charch;

creatree();

while

(1)

{

printf("输入操作方式(c/q/t)!

\n");

scanf("%s",&ch);

if(ch=='c')

{

printf("请输入需要改变的结点和权值(a,b)!

\n");

scanf("%d%d",&a,&b);

change_bt(a,b);

}

if(ch=='q')

{

printf("输入想要查询的子树的根结点序号!

\n");

scanf("%d",&n);

bitree*t;

t=&bt[n-1];

preorder(t);

printf("最大的权值为%d\n",max);

max=0;

}

if(ch=='t')

break;

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 中国风

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1