数据结构课程设计说明书.doc

上传人:zf 文档编号:30814161 上传时间:2024-01-30 格式:DOC 页数:27 大小:451.92KB
下载 相关 举报
数据结构课程设计说明书.doc_第1页
第1页 / 共27页
数据结构课程设计说明书.doc_第2页
第2页 / 共27页
数据结构课程设计说明书.doc_第3页
第3页 / 共27页
数据结构课程设计说明书.doc_第4页
第4页 / 共27页
数据结构课程设计说明书.doc_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

数据结构课程设计说明书.doc

《数据结构课程设计说明书.doc》由会员分享,可在线阅读,更多相关《数据结构课程设计说明书.doc(27页珍藏版)》请在冰豆网上搜索。

数据结构课程设计说明书.doc

*******************

实践教学

*******************

兰州理工大学

计算机与通信学院

2014年秋季学期

数据结构课程设计

题目:

猴子吃桃子问题;跳马问题;

通过单字符置换可以将一个

单词改为另一个单词

专业班级:

12级信息与计算科学

(2)班

姓名:

林承勇

学号:

12540236

指导教师:

包仲贤

成绩:

目录

摘要 1

一.猴子吃桃问题 2

1.采用类语言定义相关的数据类型 2

2.算法设计 2

3.调试分析 3

4.测试结果 4

5.源程序(带注释) 6

二.跳马问题 10

1.采用类语言定义相关的数据类型 10

2.算法设计 10

3.调试分析 11

4.测试结果 11

5.源程序(带注释) 13

三.通过单字符置换可以将一个单词改为另一个单词 16

1.采用类语言定义相关的数据类型 16

2.算法设计 16

3.调试分析 18

4.测试结果 18

5.源程序(带注释) 19

总结 23

参考文献 24

致谢 25

摘要

本程序主要主要解决猴子吃桃问题,跳马问题,通过单字符置换可以将一个单词改为另一个单词。

猴子吃桃问题是分别采用数组数据结构,链式数据结构以及递归方法根据猴子每天吃的桃子数来求解一群猴子摘的桃子数。

跳马问题也称为骑士周游问题,是算法的设计中的经典问题。

如果有这样一种走法,则称所走的这条线为马的周游路线。

在8*8的方格棋盘中马的行走规则从棋盘的某一方格出发,开始在棋盘上周游,如果能不重复地走遍棋盘上的每一个方格,这样的一条周游路线在数学上被称为国际象棋棋盘上马的哈密尔顿链。

通过单字符置换可以将一个单词改为另一个单词是假设存在一个5字母单词的字典,给出一个算法确定单词A是否可以通过一系列的单字符置换转换为单词B,并且如果可以的话,输出相应的单词序列。

正如bleed通过序列bleed、blend、blond、blood转换为blood。

这些程序主要功能是加深我们对算法与数据结构中存储,线性表和栈的理解。

让我们对算法与数据结构有个更深刻的认识。

关键词:

猴子吃桃;跳马;字符转换;数据结构

一.猴子吃桃问题

有一群猴子摘了一堆桃子,他们每天都吃当前桃子的一半且再多吃一个,到了第10天就只余下一个桃子。

用多种方法实现求出原来这群猴子共摘了多少个桃子。

要求:

1)采用数组数据结构实现上述求解;2)采用链式数据结构实现上述求解;3)采用递归实现上述求解。

1.采用类语言定义相关的数据类型

typedefstructNode{

inti;

int k;//数据域

structNode*next;//指针域

}Node,*PNode;//定义一个指针用于链表求解

2.算法设计

1.一维数组解决。

建立一个一维数组a[10]从第九天开始算起令a[9]=1利用for循环计算前八天猴子吃的桃子数目并同时将后一天吃的桃子数赋值到前一天。

最后即可得出猴子一共吃的桃子数。

2.递归函数解决:

定义一个整形函数DiGui使用if函数控制是否调用函数本身。

桃子数等与一这说明第九天吃了一个桃子函数便可以结束。

如果桃子数不为一则一直调用函数本身知道调用结束。

3链式数据结构解决:

定义头指针p1,p2指针指向头结点。

P2指针负责传值进行循环。

利用for函数进行循环。

并将后一天的之赋值给前一天。

最后便可得到猴子吃的总的桃子数。

主函数控制各子函数的调用流程如图1-1所示

4

3

2

1

退出

DiGui

ShuZu

LianBiao

结束

开始

输入n

判断n

请输入正确的选择

N

图1-1主控制程序流程图

3.调试分析

a、调试中遇到的问题及对问题的解决方法;

根据第十天所剩桃子个数,采用倒推方法,递归的求出第九天,第八天,第七天….直到算出刚开始猴子拥有桃子的总数。

解决方法主要是用递归算法采用数组存储方法。

b、算法的时间复杂度和空间复杂度。

通过1、2、3数字键选择计算方法时间复杂度为O(n),空间复杂度为O

(1)

4.测试结果

1)执行程序进入主菜单,如图1-1所示

图1-2主菜单

2)输入1用数组方法求解,如图1-2所示

图1-3数组求解

3)输入2用链表求解,如图1-3所示

图1-4链表求解

4)输入3用递归方法求解,如图1-4所示

图1-5递归求解

5)输入4退出程序,如图1-5所示

图1-6退出界面

5.源程序(带注释)

#include

#include

typedefstructNode{

inti;

int k;//数据域

structNode*next;//指针域

}Node,*PNode;//定义一个指针用于链表求解

intShuZu()//数组求解

{

inti,a[10];

a[9]=1;

for(i=8;i>=0;i--)

a[i]=(a[i+1]+1)*2;

returna[0];

}

intDiGui(inti,intj,intk)//递归求解

{

if(j==i)returnk;

k=(k+1)*2;

DiGui(i,j-1,k);

}

intLianBiao()//链表求解

{

inti;

PNodep1,p2;

if((p1=(PNode)malloc(sizeof(Node)))==NULL){//生成新的结点

printf("分配内存失败!

");

exit(0);

}

p1->i=10;

p1->k=1;

p1->next=NULL;

for(i=9;i>0;i--){

if((p2=(PNode)malloc(sizeof(Node)))==NULL){

printf("分配内存失败!

");

exit(0);

}

p2->i=9;

p2->k=(p1->k+1)*2;

p2->next=NULL;

free(p1);

p1=p2;

}

returnp1->k;

}

intmain()//主函数

{

charn;

inti,j,k;

i=ShuZu();

j=DiGui(1,10,1);

k=LianBiao();

for(;;)

{

printf("\t*******************欢迎进入猴子吃桃问题***********************\n");

printf("\t************************1.数组方法*******************************\n");

printf("\t************************2.链表方法*******************************\n");

printf("\t************************3.递归方法*******************************\n");

printf("\t************************4.退出*******************************\n");

printf("\t*****************************************************************\n");

printf("\t输入选项(1~4):

");

scanf("%s",&n);

switch(n)

{

case'1':

printf("\n");

printf("\t\t\t\t数组方法得出的总桃子数为:

%d\n",i);

printf("\n");

printf("\t\t\t\t*如需继续进入主菜单请按回车键*\n");

break;

case'2':

printf("\n");

printf("\t\t\t\t链表方法得出的总桃子数为:

%d\n",k);

printf("\n");

printf("\t\t\t\t*如需继续进入主菜单请按回车键*\n");

break;

case'3':

printf("\n");

printf("\t\t\t\t递归方法得出的总桃子数为:

%d\n",j);

printf("\n");

printf("\t\t\t\t*如需继续进入主菜单请按回车键*\n");

break;

case'4':

printf("\n");

printf("谢谢使用本系统^o^\n");

exit(0);

break;

default:

printf("\n");

printf("\n请键入一个正确的选择");

printf("\n");

printf("\t\t\t\t*如需继续进入主菜单请按回车键*\n");

break;

}

getchar();

getchar();

system("cls");

}

}

二.跳马问题

要求在64个国际象棋格子,任意位置放一个马,如何不重复地把格子走完。

1.采用类语言定义相关的数据类型

#include

typedefstructDataType

{

intboard[8][8];//定义一个int的二位数组board

intstep;/*走的步数*/

inttest;/*可以遍历成功的次数*/

}SeqList;

SeqListL;

intstart;

intdeltar[]={-2,-1,1,2,2,1,-1,-2};

intdeltac[]={1,2,2,1,-1,-2,-2,-1};/*马的可能走法对当前位置的横纵增量*/

Main()

输入r,c表示马在棋盘上的初始位置

检测是否有下一出口

(k=next(r,c))==-1)

此路不通

此路可通过

输出满足该问题的一种正确解法,程序结束。

初始化数组表示棋盘

2.算法设计

该问题分为两步首先在8*8的棋盘上的任意一个位置上放一个马(r,c),求马所在位置的出口数。

其次选择出口最少的那个位置。

函数执行流程图如

图2-1所示

图2-1函数执行流程图

3.调试分析

a、调试中遇到的问题及对问题的解决方法

对于跳马问题,一般情况下,可以采用回溯法找解,但对于该问题来说,只要找到一种解法即可。

然而,在写该问题的程序时,有时得到的不止一种,这就和“贪婪法”的思想相悖,在经过反复的思考和查阅资料之后,才明白须将if(step>64)放在do{}while(step<=64)循环语句之外,才能达到用“贪婪法”解决该问题的目的。

b、算法的时间复杂度和空间复杂度

时间复杂度的计算是按照运算次数来进行的,关于空间复杂度的计算是在程序运行过程所要借助的内容空间大小。

时间复杂度:

O(n2);空间复杂度:

O(n)。

4.测试结果

1)进入主界面如图2-1所示

图2-2主界面

2)输入初始的行列,结果如图2-2所示

图2-3输入初始数据图

3)重新设置初始行列56如图2-3所示

图2-4重新设置初始数据图

5.源程序(带注释)

#include

typedefstructDataType

{

intboard[8][8];//定义一个int的二位数组board

intstep;/*走的步数*/

inttest;/*可以遍历成功的次数*/

}SeqList;

SeqListL;

//intboard[8][8];

intstart;

intdeltar[]={-2,-1,1,2,2,1,-1,-2};

intdeltac[]={1,2,2,1,-1,-2,-2,-1};/*马的可能走法对当前位置的横纵增量*/

intexitn(intr,intc,intnexta[])

{/*求马所在位置(r,c)的出口数,nexta[]为出口号*/

inti,k,a,b;

intnum=0;

for(i=0;i<=7;i++)

{

k=(i+start)%8;

a=r+deltar[k];

b=c+deltac[k];

if(a<=7&&a>=0&&b>=0&&b<=7&&L.board[a][b]==0)

{

nexta[num]=k;

num++;

}

}

returnnum;

}

intnumber(intr,intc)

{/*返回下次可以找到的增量的个数*/

inti,k,a,b;

intnum=0;

for(i=0;i<=7;i++)

{

k=(i+start)%8;

a=r+deltar[k];

b=c+deltac[k];

if(a<=7&&a>=0&&b>=0&&b<=7&&L.board[a][b]==0)

{

num++;

}

}

returnnum;

}

intnext(intr,intc)

{/*选择下一个出口*/

intnexta[8],num,num1=0,min,i,k;/*min用来确定最少出口数*/

min=9;

num=exitn(r,c,nexta);/*num为(r,c)的出口个数*/

if(num==0)

{

return-1;/*没有出口*/

}

for(i=0;i<=num-1;i++)

{/*找出口最少的点*/

num1=number(r+deltar[nexta[i]],c+deltac[nexta[i]]);

if(num1<=min)

{

min=num1;

k=nexta[i];

}

}

returnk;/*返回出口最少的点*/

}

intmain()

{

intber,bec;/*用于保存输入初始的行列*/

intr,c;

inti,j,k;

printf("Enterthefirstnode:

(berbec)/n");

while(scanf("%d%d",&ber,&bec)!

=-1)//接收起点

{

start=0;

L.test=1;

while(start<=7)/*进行测试的次数*/

{

do

{

for(i=0;i<=7;i++)

for(j=0;j<=7;j++)

L.board[i][j]=0;/*初始化board数组*/

r=ber;/*将当前值赋给r*/

c=bec;/*将当前值赋给c*/

L.board[r][c]=1;/*将初始位置赋值为1*/

for(L.step=2;L.step<=64;L.step++)

{

if((k=next(r,c))==-1)/*此路不通*/

{

start++;

break;/*进行下一次测试*/

}

r+=deltar[k];

c+=deltac[k];

L.board[r][c]=L.step;

}

}while(L.step<=64);

if(L.step>64)/*如果步数大于棋盘的格子数,则表明遍历成功*/

{

printf("方案%d:

\n",L.test++);

for(i=0;i<=7;i++)/*打印出该方案*/

{

for(j=0;j<=7;j++)

{

printf("%4d",L.board[i][j]);

}

printf("\n\n");

}

start++;

break;

}//endif

}//endwhile(start<=7)

}//endwhile(scanf("%d%d",&ber,&bec)!

=-1)

return0;

}

三.通过单字符置换可以将一个单词改为另一个单词

假设存在一个5字母单词的字典。

给出一个算法确定单词A是否可以通过一系列的单字符置换转换为单词B,并且如果可以的话,输出相应的单词序列。

例如,bleed通过序列bleed、blend、blond、blood转换为blood。

1.采用类语言定义相关的数据类型

#defineLEN6

#defineLINE23

#defineMAXVALUE100

typedefstructDataType

{

intgraph[LINE][LINE];//定义一个int的二位数组graph

inta[LINE][LINE];

intpath[LINE][LINE];

}SeqList;

chardic[LINE][LEN]={"bland","blank","bleak","bleed","blend",

"blind","blink","blond","blood","bloom","blown","blows","brand",

"brank","bread","break","bream","breed","brown","clank","clink",

"dread","dream"};//定义一个由5个字母组成的字典

booledge_test(charsource[],chartarget[]);

2.算法设计

最初简单的想法是,对于第一个给定的单词,将其中的任意字母替换,循环查找是否可以变换为另一个单词,但仔细思考发现,事实上这种方法是很难到达循环结束终点的,因为其中的变换步骤是不定的,也就是说单词可以通过有限步变到另一个单词,只要存在变换,这种方法就是可行解。

于是想到将任意单词抽象为节点,任意两个单词之间可以通过变换一个字母到达的变换可以抽象为图中两个节点是相连通的,而不能仅通过替换一个字母变换就到达终点的两个节点之间是不连通的,问题变为如果任意两个单词之间存在可行解,意味着图中两个单词是连通的。

我们发现,寻找两个节点的通路就能找到一种解法。

所以可以查找图中两个节点之间的最短路径,用Floyd算法进行求解,Floyd算法直接给出了所有节点之间的最短路径。

若不存在路径的情况,即两个节点之间没有可达的路径,则这两个节点必定存在不同的连通分支中,意味着字典中的词是存在着至少两个连通分支的。

Floyd算法流程图如图3-1所示

Y

N

Y

N

开始

L.a[i][j]=L.graph[i][j]

i!

=j&&L.a[i][j]

L.path[i][j]=0

L.path[i][j]=i

L.a[i][k]+L.a[k][j]

L.a[i][j]=L.a[i][k]+L.a[k][j];

L.path[i][j]=L.path[k][j]

结束

图3-1Floyd算法执行流程图

3.调试分析

a、调试中遇到的问题及对问题的解决方法

调试过程出现了edge_test没定义的问题,解决办法是在最前面加上

booledge_test(charsource[],chartarget[]);

b、算法的时间复杂度和空间复杂度

该算法的复杂度为O(n³);空间复杂度为O(n)

4.测试结果

1)执行程序进入主界面,如图3-1所示

图3-1主界面

2)输入bleedblood,输出结果如图3-2所示

3-2结果输出

5.源程序(带注释)

#include

#include

#defineLEN6

#defineLINE23

#defineMAXVALUE100

typedefstructDataType

{

intgraph[LINE][LINE];//定义一个int的二位数组graph

inta[LINE][LINE];

intpath[LINE][LINE];

}SeqList;

chardic[LINE][LEN]={"bland","blank","bleak","bleed","blend","blind","blink","blond",

"blood","bloom","blown

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

当前位置:首页 > 医药卫生 > 基础医学

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

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