猴子吃桃问题数据结构课程设计.docx
《猴子吃桃问题数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《猴子吃桃问题数据结构课程设计.docx(20页珍藏版)》请在冰豆网上搜索。
猴子吃桃问题数据结构课程设计
一、设计题目 猴子吃桃子问题
有一群猴子摘了一堆桃子,他们每天都吃当前桃子的一半且再多吃一
个,到了第10天就只余下一个桃子。
用多种方法实现求出原来这群猴子共摘了多少个桃子。
二、运行环境(软、硬件环境)
VC++6.0PC电脑一台
三、算法的需求分析
1) 采用数组数据结构实现上述求解
2) 采用链数据结构实现上述求解
3) 采用递归实现上述求解
4) 如果采用4种方法者,适当加分
//用户界面
intDesk(intn)
{
printf("**************************************************\n");
printf("|欢迎进入猴子吃桃子系统|\n");
printf("|1-数组法2-链表法3-递归法4-二叉树法5-退出|\n");
printf("***************************************************\n");
printf("请输入要选择的方法:
");
scanf("%d",&n);
getchar();
system("cls");//刷新屏幕
while(n<1||n>5)
{
printf("***输入错误!
请重新输入***\n");
scanf("%d",&n);
}
returnn;
}
四、算法概要设计
//采用链数据结构(栈)实现上述求解
typedefstruct
{
int*top;
int*base;
}stack;
//初始化一个栈
stackInit(stack*s)
{
s->base=(int*)malloc(STACK_SIZE*sizeof(int));
if(s->base==NULL)
{
printf("Initfailed!
\n");
exit(-1);
}
s->top=s->base;
return*s;
}
//二叉树
创建一个大小为DAYS(由用给出)的二叉树,二叉树的左孩子节点存放当天的桃子数,右节点存放数字1,即为多吃的一个桃子。
typedefstructTNode
{
intdata;
structTNode*lchild;
structTNode*rchild;
}tree;
//创建一个二叉树
treeCreatTree(tree*T)//T为指针类型
{
intn=0,i=0;
tree*p,*pr,*T1;
T=(tree*)malloc(sizeof(TNode));
T1=T;
T->data=1;//根节点内的数据为第DAYS天的桃子数
for(i=1;i{
p=(tree*)malloc(sizeof(TNode));
pr=(tree*)malloc(sizeof(TNode));
pr->lchild=NULL;
pr->rchild=NULL;
p->data=0;
pr->data=1;
T1->lchild=p;
T1->rchild=pr;
T1=p;
}
T1->lchild=NULL;
T1->rchild=NULL;
return*T;//返回T的地址
}
//算法框架图
N
YN
Y
五、算法详细设计
#include
#include
#include"peach.h"
//函数声明
intDesk(intn);
voidpeach_1(void);
stackInit(stack*s);
voidPush(stack*s,intnum);
voidPop(stack*s,int&num);
voidpeach_2(stack*s);
voidpeach_3(intn,inti);
treeCreatTree(tree*T);
voidcalculate(tree*T);
voidpeach_4(tree*T);
intmain()
{
intdata=0;
intn=1,i=1;
stacks;
treeT;
s=Init(&s);
T=CreatTree(&T);
while
(1)
{
switch(Desk(n))
{
case1:
peach_1();
break;
case2:
peach_2(&s);
break;
case3:
peach_3(n,i);
break;
case4:
peach_4(&T);
break;
case5:
exit(0);
break;
}
}
return0;
}
//头文件代码
#defineDAYS10//定义给定的天数
#defineSTACK_SIZE5//栈的容量,实际只用了一个
#defineTRUE1
#defineERROR0
voidpeach_3(intn,inti);
//用户界面
intDesk(intn)
{
printf("**************************************************\n");
printf("|欢迎进入猴子吃桃子系统|\n");
printf("|1-数组法2-链表法3-递归法4-二叉树法5-退出|\n");
printf("***************************************************\n");
printf("请选择要使用的方法:
");
scanf("%d",&n);
getchar();
system("cls");//刷新屏幕
while(n<1||n>5)
{
printf("***输入错误!
请重新输入***\n");
scanf("%d",&n);
}
returnn;
}
//采用数组数据结构实现上述求解
voidpeach_1(void)
{
intpeach[50]={0};
inti=0,j=0;
peach[DAYS-1]=1;//最后一天的桃子数
for(i=DAYS;i>0;--i,j=i-1)
{
peach[j]=2*(peach[i]+1);
}
printf("*********************\n");
printf("*数组法*\n");
printf("*这群猴子共摘了%d个桃子*\n",peach[0]);
printf("*********************\n");
}
//采用链数据结构实现上述求解
typedefstruct
{
int*top;
int*base;
}stack;
//初始化一个栈
stackInit(stack*s)
{
s->base=(int*)malloc(STACK_SIZE*sizeof(int));
if(s->base==NULL)
{
printf("Initfailed!
\n");
exit(-1);
}
s->top=s->base;
return*s;
}
//把当天的桃子数进栈
voidPush(stack*s,intnum)
{
*s->top++=2*(num+1);
}
//把前一天的桃子数出栈
voidPop(stack*s,int&num)//&num位地址传递,可以直接对参数进行修改
{
num=*--s->top;
}
voidpeach_2(stack*s)
{
inti=0;
intnum=0;
Push(s,1);//先把最后一天的桃子数进栈
i++;
while(i{
Pop(s,num);
Push(s,num);
i++;
}
printf("*********************\n");
printf("*链表法*\n");
printf("*这群猴子共摘了%d个桃子*\n",num);
printf("*********************\n");
}
voidpeach_3(intn,inti)
{
if(i==DAYS)//DAYS为递归终止条件由用户给出
{
printf("*********************\n");
printf("*递归法*\n");
printf("*这群猴子共摘了%d个桃子*\n",n);
printf("*********************\n");
}
else
{
n=2*(n+1);
peach_3(n,i+1);
}
}
//二叉树
typedefstructTNode
{
intdata;
structTNode*lchild;
structTNode*rchild;
}tree;
treeCreatTree(tree*T)//T为指针类型
{
intn=0,i=0;
tree*p,*pr,*T1;
T=(tree*)malloc(sizeof(TNode));
T1=T;
T->data=1;//根节点内的数据为第DAYS天的桃子数
for(i=1;i{
p=(tree*)malloc(sizeof(TNode));
pr=(tree*)malloc(sizeof(TNode));
pr->lchild=NULL;
pr->rchild=NULL;
p->data=0;
pr->data=1;
T1->lchild=p;
T1->rchild=pr;
T1=p;
}
T1->lchild=NULL;
T1->rchild=NULL;
return*T;//返回T的地址
}
//对二叉树进行赋值计算
voidcalculate(tree*T)
{
inti=0;
tree*T1,*T2,*T3;//T1,T3分别为T2的左右孩子
T2=T;
for(i=0;i{
T1=T2->lchild;
T3=T2->rchild;
T1->data=2*(T2->data+T3->data);
T2=T1;
}
}
//二叉树遍历最左下角的孩子节点
voidpeach_4(tree*T)
{
calculate(T);
while(T->lchild!
=NULL)
{
T=T->lchild;
}
printf("*********************\n");
printf("*二叉树法*\n");
printf("*这群猴子共摘了%d个桃子*\n",T->data);
printf("*********************\n");
}
六、算法的测试
//主函数
#include
#include
#include"peach.h"
//函数声明
intDesk(intn);
voidpeach_1(void);
stackInit(stack*s);
voidPush(stack*s,intnum);
voidPop(stack*s,int&num);
voidpeach_2(stack*s);
voidpeach_3(intn,inti);
treeCreatTree(tree*T);
voidcalculate(tree*T);
voidpeach_4(tree*T);
intmain()
{
intdata=0;
intn=1,i=1;
stacks;
treeT;
s=Init(&s);
T=CreatTree(&T);
while
(1)
{
switch(Desk(n))
{
case1:
peach_1();
break;
case2:
peach_2(&s);
break;
case3:
peach_3(n,i);
break;
case4:
peach_4(&T);
break;
case5:
exit(0);
break;
}
}
return0;
}
//采用数组数据结构实现上述求解
voidpeach_1(void)
{
intpeach[50]={0};
inti=0,j=0;
peach[DAYS-1]=1;//最后一天的桃子数
for(i=DAYS;i>0;--i,j=i-1)
{
peach[j]=2*(peach[i]+1);
}
printf("*********************\n");
printf("*数组法*\n");
printf("*这群猴子共摘了%d个桃子*\n",peach[0]);
printf("*********************\n");
}
voidpeach_2(stack*s)
{
inti=0;
intnum=0;
Push(s,1);//先把最后一天的桃子数进栈
i++;
while(i{
Pop(s,num);
Push(s,num);
i++;
}
printf("*********************\n");
printf("*链表法*\n");
printf("*这群猴子共摘了%d个桃子*\n",num);
printf("*********************\n");
}
voidpeach_3(intn,inti)
{
if(i==DAYS)//DAYS为递归终止条件由用户给出
{
printf("*********************\n");
printf("*递归法*\n");
printf("*这群猴子共摘了%d个桃子*\n",n);
printf("*********************\n");
}
else
{
n=2*(n+1);
peach_3(n,i+1);//循环体
}
}
//二叉树遍历最左下角的孩子节点
voidpeach_4(tree*T)
{
calculate(T);
while(T->lchild!
=NULL)
{
T=T->lchild;
}
printf("*********************\n");
printf("*二叉树法*\n");
printf("*这群猴子共摘了%d个桃子*\n",T->data);
printf("*********************\n");
}
七、运行结果分析
1、数组法:
创建一个大小为DAYS的一维数组a[DAYS],a[0],a[1]...a[DAYS-1]分别存放当天的桃子数,其中a[n]=2*(a[n-1]+1)。
2、链表法:
创建一个链栈,先把第DAYS天的桃子数进栈,然后出栈,把出战的数据num进行处理,即num=2*(num+1),然后继续进栈,出栈如此反复循环DAYS次结束。
3、递归法:
首先确定递归的终止条件,即i=DAYS(假设i的初始值为1),循环体为
fac(n,i+1),在递归过程中对n进行如下处理,n=2*(n+1)。
4、二叉树法:
创建一个大小为DAYS的二叉树,其中根节点为第DAYS天的桃子数,其中根节点的左孩子为上一天的桃子数,右孩子只存一个固定数据,即数字1。
对二叉树作如下处理,对于一个根节点,其左孩子=2*(根节点+右孩子)。
经过一系列的调试运行,该程序可以正确执行,并能够按要求完成任务。
八、收获及体会
通过设计猴子吃桃子这一程序,是我对C语言以及数据结构有了更深的了解,通过编写代码,是我学习和掌握了C的理论知识和实践程序设计的各种技能。
在编写代码时也遇到了很多麻烦,例如在用递归编写时,突然忘了递归在系统栈内是如何运行的,于是我向同学和老师虚心请教。
另外在用二叉树时,根节点T总是没有正确定位,使其成为了野指针。
总而言之,通过这一课程设计的学习,我对C程序有了更深的认识。
我深信,一个良好的程序员需要不断去敲写代码,在实践中总结经验,从而提高自己的综合实践能力,去为社会最初更大的奉献。
最后我要感谢我的同学以及汪文彬老师对我的帮助,我所取得的进步与他们的热心帮助是离不开的。
九、主要参考文献:
[1]苏小红C语言大学实用教程(第二版)电子工业出版社
[2]数据结构C语言版严蔚敏清华大学出版社
[3]C程序设计谭浩强第三版清华大学出版社