线性表和图表的应用.docx
- 文档编号:24866526
- 上传时间:2023-06-02
- 格式:DOCX
- 页数:12
- 大小:57.44KB
线性表和图表的应用.docx
《线性表和图表的应用.docx》由会员分享,可在线阅读,更多相关《线性表和图表的应用.docx(12页珍藏版)》请在冰豆网上搜索。
线性表和图表的应用
通信与电子工程学院
2007级数据结构课程设计报告
姓名:
学号:
班级:
通信与电子工程学院
2007级数据结构课程设计报告
课程名称:
数据结构课程设计名称:
线性表和图的应用指导老师:
设计时间:
5月22日~6月12日提交时间:
6月12日姓名:
班级:
学号:
成绩:
一、课程设计的目的和要求
1.了解线性表(包括栈、队列、串、数组)和图的逻辑结构特性。
2.熟练掌握各种线性结构的顺序表达和链式表达的定义与实现,包括查找、插入、删除算法的实现;
3.熟练掌握图的邻接矩阵存储方式与实现,包括图的深度和广度遍历优先算法的实现
4.能够从时间和空间复杂度的角度综合比较各种存储结构的不同特点,能够根据实际问题选择一种比较好的结构解决问题。
二、设计过程描述
1.有M只猴子围成一圈,每只各一个从1到M中的编号,打算从中选出一个大王;经过协商,决定出选大王的规则:
从第一个开始循环报数,数到N的猴子出圈,最后剩下来的就是大王。
要求:
从键盘输入M、N,编程计算哪一个编号的猴子成为大王。
程序首先定义一个结构体如下,其中num用来指示猴子的编号;结构体类型的指针link放在链表中操作;以及一个结构体变量monkey;
typedefstructmonkey
{
intnum;
structmonkey*next;
}monkey,*link;
建立一个无返回值得main()函数,其头文件名为#include
执行head=p=p2=(LINK)malloc(sizeof(Monkey)),由系统生成一个LNode型的结点,同时将该结点的起始位置赋给指针变量p,使得三个指针指向同一块内存。
建立一个循环结构,令p指向第一个结点,并从第一个结点到最后一个结点依次给猴子编号,当p指向了最后一个结点时候,循环结束,如下:
p2->next=head;//把链表的首尾相连
p=head;//p指向了第一个结点
printf("对猴子进行编号!
\n");
for(i=1;i<=n;i++)
{
p->num=i;//从第一个结点到最后一个结点依次给猴子编号
printf("%d号猴子:
%d\n",p->num,p->num);
p=p->next;
}
再次把p指向第一个结点,构造一个循环结构,如下:
while
(1)
{
i++;
printf("%d号猴子报:
%d\n",p->num,i);
if(p->next==p)
break;
其中的breakfast即为此循环的出路。
报到号码m的猴子被淘汰,在此删除此结点,并令指针指向下一个结点,如此循环而行。
否则,就要保存将要退出结点的前一个结点(存到p2中)。
这样,直到最后选出大王为止。
2.用栈实现以邻接矩阵作存储结构图的深度优先搜索。
首先给邻接数组分配储存空间,如下:
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
建立主函数main(),其中调用CreateMGraph(&G)和DFSM(&G,0),功能如下:
voidCreateMGraph(MGraph*G)
初始条件:
操作结果:
创建图G
voidDFSM(MGraph*G,inti)
初始条件:
图G已经创建
操作结果:
深度优先递归遍历图G
voidPush(SqStack*S,inte)
初始条件:
栈S已存在
操作结果:
插入元素e为新的栈顶元素
Pop(&S,&e)
初始条件:
栈S已存在
操作结果:
删除S的栈顶元素,并用e返回其值
在CreateMGraph(&G)函数中,对图的边及其关系做初始化,如下:
G->vexs[i]=getchar();
for(i=0;i
for(j=0;j
G->edges[i][j]=0;
在DFSM(&G,0)函数中,当栈非空是,执行如下循环:
while(!
StackEmpty(&S))
{
i=Pop(&S);
j=0;
while(j
{
if(G->edges[i][j]==1&&!
visited[j])
{
printf("访问:
%c",G->vexs[j]);
visited[j]=1;
Push(&S,j);
}
三、结果分析
1.循环链表是另外一种形式的链式存储结构。
它的特点是表中最后的一个结点的指针域指向头结点整个链表形成一个环。
由此,从表中任意结点出发均可找到表中的其他结点。
循环链表的操作和线性链表基本一致,差别仅在于算法中的循环条件不是p活p->next是否为空,而是它们是否等于头指针。
但有的时候,若在循环链表中设立尾指针,可使某些操作简化。
在猴子选大王的问题中,主要就是运用了循环链表的功能。
在编写语句head=newnode和q=newnode时,刚开始使用的是C中的malloc,且语法格式也搞错了,经过多次调节才解决问题。
有的同学认为C++中的new比较方便,且自动返回正确的指针类型,事实的确如此,我也因此而受到了启发。
但是,不论是C的malloc(),free();或是C++的new和delete都很费时间,所以我们可以想办法减少空间分配和回收的次数来提高效率。
运行结果图如下,由于运行结果太长,若全部截取,可能会大量浪费版面,因此在此只截取部分图片:
由于运行结果太长,若全部截取,可能会大量浪费版面,因此在此只截取部分图片。
2.用栈实现以邻接矩阵作存储结构图的深度优先搜索
借助于邻接矩阵,容易判定任意两个顶点之间是否有边相连,并容易求得各个顶点的度。
而栈是一个先进后出的线性表,与递归有着密切的联系。
本算法就是采用栈来存储,通过入栈存储被访问过的顶点和其中的某一个连接点,再通过取栈顶元素的值和出栈等,取出未被访问的元素的连接点进行访问,然后就是重复上述操作。
图的深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广,假设初时状态是途中所有的顶点未曾被访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度遍历图,直至图中所有和v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问到为止,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,直至图中所有顶点都被访问到为止。
依照本算法,运行出来的结果如下,但是似乎存在着一定得问题:
四、附录代码
//猴子选大王循环链表代码
#include
#include
typedefstructmonkey
{
intnum;
structmonkey*next;
}Monkey,*LINK;
voidmain()
{intn;intm;
printf("请输入猴子的总数和报到多少时猴子被淘汰:
例如(n,m)");
scanf("%d,%d",&n,&m);
LINKp,head,p2;
inti;
head=p=p2=(LINK)malloc(sizeof(Monkey));//三个指针指向同一块内存
for(i=1;i { p=(LINK)malloc(sizeof(Monkey)); p2->next=p; p2=p; } p2->next=head;//把链表的首尾相连 p=head;//p指向了第一个结点 printf("对猴子进行编号! \n"); for(i=1;i<=n;i++) { p->num=i;//从第一个结点到最后一个结点依次给猴子编号 printf("%d号猴子: %d\n",p->num,p->num); p=p->next; }//循环结束,p指向了最后一个结点 i=0; p=head;//再把p指向第一个结点 while (1) { i++; printf("%d号猴子报: %d\n",p->num,i); if(p->next==p) break;//此为while循环的出口 if(i==m)//if语句中是删除结点的过程 { i=0; printf("%d号猴被淘汰\n",p->num); printf("\n"); p2->next=p->next;//在此删除结点p p=p2->next;//p指向它的下一个结点 continue; } else { if(i==m-1) p2=p;//保存将要退出结点的前一个结点(存到p2中) p=p->next; } } printf("猴子大王是第%d号猴子\n",p->num);//最后剩下的结点就是获胜的结点 } //深度优先遍历 #include #include #include #defineSTACK_INIT_SIZE100 #defineSTACKINCREMENT10 intvisited[20]={0}; typedefstruct { charvexs[20];/*顶点表*/ intedges[20][20]; intn,e; }Mgraph; typedefstructBiTNode { intdata; structBiTNode*lchild,*rchild; } BiTNode,*BiTree; typedefstructSqStack { int*base; int*top; intstacksize; } SqStack; voidInitStack(SqStack*S) { S->base=(int*)malloc(STACK_INIT_SIZE*sizeof(int)); S->top=S->base; S->stacksize=STACK_INIT_SIZE; } voidPush(SqStack*S,inte) { if(S->top-S->base>=S->stacksize) { S->base=(int*)realloc(S->base, (S->stacksize+STACKINCREMENT)*sizeof(int)); S->top=S->base+S->stacksize; S->stacksize+=STACKINCREMENT; } *(S->top)=e; S->top++; } intPop(SqStack*S) { S->top--; return*S->top; } intStackEmpty(SqStack*S) { if(S->top==S->base) return1; else return0; } voidCreateMGraph(Mgraph*G) { inti,j,k; printf("输入顶点和边数\n"); scanf("%d%d",&G->n,&G->e); getchar(); printf("输入%d个顶点\n",G->n); for(i=0;i G->vexs[i]=getchar(); for(i=0;i for(j=0;j G->edges[i][j]=0; printf("输入%d条边: \n",G->e); for(k=0;k { scanf("%d%d",&i,&j); G->edges[i][j]=1; } } voidDFSM(Mgraph*G,inti) { intj;SqStackS; InitStack(&S); printf("访问: %c",G->vexs[i]); visited[i]=1; Push(&S,i); while(! StackEmpty(&S)) { i=Pop(&S); j=0; while(j { if(G->edges[i][j]==1&&! visited[j]) { printf("访问: %c",G->vexs[j]); visited[j]=1; Push(&S,j); } else j++; } } } main() { MgraphG; CreateMGraph(&G); DFSM(&G,0); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 线性 图表 应用