拓扑排序(算法与数据结构课程设计)

拓扑排序(算法与数据结构课程设计)
拓扑排序(算法与数据结构课程设计)

拓扑排序

一、问题描述

在AOV网中为了更好地完成工程,必须满足活动之间先后关系,需要将各活动排一个先后次序即为拓扑排序。拓扑排序可以应用于教学计划的安排,根据课程之间的依赖关系,制定课程安排计划。按照用户输入的课程数,课程间的先后关系数目以及课程间两两间的先后关系,程序执行后会给出符合拓扑排序的课程安排计划。

二、基本要求

1、选择合适的存储结构,建立有向无环图,并输出该图;

2、实现拓扑排序算法;

3、运用拓扑排序实现对教学计划安排的检验。

三、算法思想

1、采用邻接表存储结构实现有向图;有向图需通过顶点数、弧数、顶点以及弧等信息建立。

2、拓扑排序算法void TopologicalSort(ALGraph G) 中,先输出入度为零的顶点,而后输出新的入度为零的顶点,此操作可利用栈或队列实现。考虑到教学计划安排的实际情况,一般先学基础课(入度为零),再学专业课(入度不为零),与队列先进先出的特点相符,故采用队列实现。

3、拓扑排序算法void TopologicalSort(ALGraph G),大体思想为:

1)遍历有向图各顶点的入度,将所有入度为零的顶点入队列;

2)队列非空时,输出一个顶点,并对输出的顶点数计数;

3)该顶点的所有邻接点入度减一,若减一后入度为零则入队列;

4)重复2)、3),直到队列为空,若输出的顶点数与图的顶点数相等则该图可拓扑排序,否则图中有环。

4、要对教学计划安排进行检验,因此编写了检测用户输入的课程序列是否是拓扑序列的算法void TopSortCheck(ALGraph G),大体思想为:

1)用户输入待检测的课程序列,将其存入数组;

2)检查课程序列下一个元素是否是图中的顶点(课程),是则执行3),否则输出“课程XX 不存在”并跳出;

3)判断该顶点的入度是否为零,是则执行4),否则输出“入度不为零”并跳出;

4)该顶点的所有邻接点入度减一;

5)重复2)、3)、4)直到课程序列中所有元素均被遍历,则该序列是拓扑序列,否则不是拓扑序列。

四、数据结构

1、链式队列的存储类型为:

typedef int ElemType;

typedef struct QNode

{ ElemType data;

struct QNode *next;

} QNode,*QueuePtr;

typedef struct

{ QueuePtr front;

QueuePtr rear;

} LinkQueue;

2、图的类型(邻接表存储结构)为:

typedef char VertexType[20];//顶点信息(名称)

typedef struct ArcNode//链表结点

{ int vexpos;//该弧所指向的顶点在数组中的位置

struct ArcNode *next;//指向当前起点的下一条弧的指针} ArcNode;

typedef struct VNode//头结点

{ VertexType name;//顶点信息(名称)

int indegree;//顶点入度

ArcNode *firstarc;//指向当前顶点的第一条弧的指针} VNode,AdjList[MAX_VERTEX_NUM];

typedef struct

{ AdjList vexhead;//邻接表头结点数组

int vexnum,arcnum;//图的顶点数和弧数

} ALGraph;

五、模块划分

1、链式队列操作

1) void InitQueue(LinkQueue *Q)

功能:初始化链式队列

参数:*Q 待初始化的队列

2) int QueueEmpty(LinkQueue Q)

功能:判断空队列

参数:Q 待判断的队列

返回值:队列为空返回 1;队列非空返回 0

3) void EnQueue(LinkQueue *Q, ElemType e)

功能:元素入队列

参数:*Q 待操作的队列;e 要入队列的元素

4) void DeQueue(LinkQueue *Q, ElemType *e)

功能:元素出队列

参数:*Q 待操作的队列;*e 记录出队列元素的变量

2、有向图(DAG)邻接表存储结构(ALG)的操作

1) int LocateVex(ALGraph G,VertexType v)

功能:顶点在头结点数组中的定位

参数:G 待操作的图;v 要在图中定位的顶点

返回值:顶点存在则返回在头结点数组中的下标;否则返回图的顶点数

2) int CreateGraph(ALGraph *G)

功能:建立图

函数内包含了由用户输入顶点数、弧数、顶点以及弧的操作

参数:*G 待操作的图

返回值:图建立成功返回1;图建立失败返回0

错误判断:包含顶点数、弧数是否正确的判断;

包含用户输入的弧的顶点是否存在的判断

3) void PrintGraph(ALGraph G)

功能:输出有向图

参数:G 待输出的图

4) int CreateGraph2(ALGraph *G)

功能:建立预置课程图(输出函数内预置课程信息,并自动建立有向图)参数:*G 待操作的图

返回值:图建立成功返回1;图建立失败返回0

错误判断:包含顶点数、弧数是否正确的判断

包含弧的顶点是否存在的判断

5) void PrintGraph2(ALGraph G)

功能:输出预置课程图

参数:G 待输出的图

3、拓扑排序及拓扑检测算法

1) void TopologicalSort(ALGraph G)

功能:实现拓扑排序

参数:G 待进行拓扑排序的图

错误判断:包含有向图是否有环的判断

2) void TopSortCheck(ALGraph G)

功能:运用拓扑排序的思想检测教学计划

函数内包含了由用户输入待检测的课程序列的操作参数:G 待操作的图

错误判断:包含用户输入的课程是否存在的判断

包含不是拓扑序列的原因(该课程有多少个先决课程未学)4、主函数

void main()

功能:主函数

利用while语句和switch语句实现菜单化调用函数六、源程序

#include "stdlib.h"

#include "stdio.h"

#include "string.h"

/*******************************************/

/* 以下为链式队列操作 */

/*******************************************/

/* 定义链式队列类型 */

typedef int ElemType;

typedef struct QNode

{ ElemType data;

struct QNode *next;

} QNode,*QueuePtr;

typedef struct

{ QueuePtr front;

QueuePtr rear;

} LinkQueue;

/* 1.初始化链式队列 */

void InitQueue(LinkQueue *Q)

{ Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));

if (!(Q->front)) exit(0);

Q->front->next=NULL; }

/* 2.判断空队列 */

int QueueEmpty(LinkQueue Q)

{ if(Q.front==Q.rear)

return 1;

else

return 0; }

/* 3.入队列 */

void EnQueue(LinkQueue *Q, ElemType e)

{ QueuePtr p;

p=(QueuePtr)malloc(sizeof(QNode));

if (!p) exit(0);

p->data=e; p->next=NULL;

Q->rear->next=p;

Q->rear=p; }

/* 4.出队列 */

void DeQueue(LinkQueue *Q, ElemType *e)

{ QueuePtr p;

if(Q->front!=Q->rear)

{ p=Q->front->next;

*e=p->data;

Q->front->next=p->next;

if (Q->rear==p) Q->rear=Q->front;

free(p); }

}

/****************************************************/

/* 以下为有向图(DAG)邻接表存储结构(ALG)的操作 */

/****************************************************/

#define MAX_VERTEX_NUM 20 //最大顶点个数

typedef char VertexType[20]; //顶点信息(名称)

/* 图的类型定义(邻接表存储结构) */

typedef struct ArcNode //链表结点

{ int vexpos; //该弧所指向的顶点在数组中的位置

struct ArcNode *next; //指向当前起点的下一条弧的指针

} ArcNode;

typedef struct VNode //头结点

{ VertexType name; //顶点信息(名称)

int indegree; //顶点入度

ArcNode *firstarc; //指向当前顶点的第一条弧的指针

} VNode,AdjList[MAX_VERTEX_NUM];

typedef struct

{ AdjList vexhead; //邻接表头结点数组

int vexnum,arcnum; //图的顶点数和弧数

} ALGraph;

/* 5.顶点在头结点数组中的定位 */

int LocateVex(ALGraph G,VertexType v)

{ int i;

for(i=0;i

if(strcmp(v,G.vexhead[i].name)==0) break;

return i; }

/* 6.建立图(邻接表) */

int CreateGraph(ALGraph *G) //成功建立返回1,不成功则返回0

{ int i,j,k; VertexType v1,v2;ArcNode *newarc;

printf("\n输入有向图顶点数和弧数vexnum,arcnum:"); //输入顶点数和弧数

scanf("%d,%d",&(*G).vexnum,&(*G).arcnum); //输入并判断顶点数和弧数是否正确if((*G).vexnum<0||(*G).arcnum<0||(*G).arcnum>(*G).vexnum*((*G).vexnum-1)) { printf("\n顶点数或弧数不正确,有向图建立失败!\n");return 0; } printf("\n输入 %d 个顶点:",(*G).vexnum); //输入顶点名称

for(i=0;i<(*G).vexnum;i++)

{ scanf("%s",(*G).vexhead[i].name); }

printf("\n顶点列表:\n共有%d个顶点: ",(*G).vexnum);//输出顶点名称

for(i=0;i<(*G).vexnum;i++)

printf("%s ",(*G).vexhead[i].name);

for(i=0;i<(*G).vexnum;i++) //邻接表初始化

{ (*G).vexhead[i].firstarc=NULL;

(*G).vexhead[i].indegree=0;}

printf("\n\n输入 %d 条边:vi vj\n",(*G).arcnum); //输入有向图的边

for(k=0;k<(*G).arcnum;k++)

{ scanf("%s%s",v1,v2); //v1是弧的起点(先决条件),v2是弧的终点i=LocateVex(*G,v1);j=LocateVex(*G,v2); //定位顶点并判断顶点是否存在

if(i>=(*G).vexnum)

{ printf("顶点%s不存在,有向图建立失败!\n",v1);return 0; } if(j>=(*G).vexnum)

{ printf("顶点%s不存在,有向图建立失败!\n",v2);return 0; } newarc=(ArcNode*)malloc(sizeof(ArcNode)); //前插法建顶点链表

newarc->vexpos=j;

if((*G).vexhead[i].firstarc==NULL)

{ newarc->next=NULL;

(*G).vexhead[i].firstarc=newarc; }

else

{ newarc->next=(*G).vexhead[i].firstarc->next;

(*G).vexhead[i].firstarc->next=newarc; }

(*G).vexhead[j].indegree++; //对应顶点入度计数加1

}

printf("\n有向图建立成功!\n");

return 1;

}

/* 7.按邻接表方式输出有向图 */

void PrintGraph(ALGraph G)

{ int i;ArcNode *p;

printf("\n输出有向图:\n");

for(i=0; i

{ printf("\n顶点:%s ",G.vexhead[i].name);

printf("入度:%3d\n",G.vexhead[i].indegree);

p=G.vexhead[i].firstarc;

printf("邻接点:");

while(p!=NULL)

{ printf("%s ",G.vexhead[p->vexpos].name);

p=p->next; }

printf("\n");

}

}

//为避免演示时要输入过多数据,以下函数将课程编号、课程间的先后关系通过数组预置

/* 8.建立预置课程图(邻接表) */

int CreateGraph2(ALGraph *G) //成功建立返回1,不成功则返回0

{ int i,j,k; VertexType v1,v2; ArcNode *newarc;

VertexType SubjectName[12]={ "C1","C2","C3","C4", //课程名称

"C5","C6","C7","C8",

"C9","C10","C11","C12" },

RelationV1[16]={ "C1","C1","C2","C1", //基础课

"C3","C4","C11","C5",

"C3","C3","C6","C9",

"C9","C9","C10","C11"},

RelationV2[16]={ "C2","C3","C3","C4", //以上面课程为基础的课"C5","C5","C6","C7",

"C7","C8","C8","C10",

"C11","C12","C12","C12",};

/* 输出本程序使用的课程及先后关系表 */

printf("\n本程序预置了如下课程及先后关系:\n");

printf("\n课程编号课程名称先决条件\n\

C1 程序设计基础无\n\

C2 离散数学 C1\n\

C3 数据结构 C1,C2\n\

C4 汇编语言 C1\n\

C5 语言的设计和分析 C3,C4\n\

C6 计算机原理 C11\n\

C7 编译原理 C5,C3\n\

C8 操作系统 C3,C6\n\

C9 高等数学无\n\

C10 线性代数 C9\n\

C11 普通物理 C9\n\

C12 数值分析 C9,C10,C1\n");

system("PAUSE");

(*G).vexnum=12; (*G).arcnum=16;

if((*G).vexnum<0||(*G).arcnum<0||(*G).arcnum>(*G).vexnum*((*G).vexnum-1)) { printf("\n课程数或先后关系不正确,有向图建立失败!\n");

return 0;} //判断课程数和弧数是否正确

for(i=0;i<(*G).vexnum;i++)

{ strcpy((*G).vexhead[i].name,SubjectName[i]); }

for(i=0;i<(*G).vexnum;i++) //邻接表初始化

{ (*G).vexhead[i].firstarc=NULL;

(*G).vexhead[i].indegree=0; }

for(k=0;k<(*G).arcnum;k++)

{ strcpy(v1,RelationV1[k]); strcpy(v2,RelationV2[k]);

i=LocateVex(*G,v1);j=LocateVex(*G,v2); //定位课程并判断课程是否存在

if(i>=(*G).vexnum)

{ printf("课程%s不存在,有向图建立失败!\n",v1);return 0; } if(j>=(*G).vexnum)

{ printf("课程%s不存在,有向图建立失败!\n",v2);return 0; }

newarc=(ArcNode*)malloc(sizeof(ArcNode)); //前插法建课程链表

newarc->vexpos=j;

if((*G).vexhead[i].firstarc==NULL)

{ newarc->next=NULL;

(*G).vexhead[i].firstarc=newarc; }

else

{ newarc->next=(*G).vexhead[i].firstarc->next;

(*G).vexhead[i].firstarc->next=newarc; }

(*G).vexhead[j].indegree++; //对应课程入度计数加1 }

printf("\n有向图建立成功!\n");

return 1;

}

/* 9.按邻接表方式输出预置课程图 */

void PrintGraph2(ALGraph G)

{ int i;ArcNode *p;

printf("\n输出有向图:\n");

for(i=0; i

{ printf("\n课程:%s ",G.vexhead[i].name);

printf("入度:%3d\n",G.vexhead[i].indegree);

p=G.vexhead[i].firstarc;

printf("以本课程为基础的课程:");

while(p!=NULL)

{ printf("%s ",G.vexhead[p->vexpos].name);

p=p->next;

}

printf("\n");

}

}

/**********************************/

/* 以下为拓扑排序算法 */

/**********************************/

/* 10.拓扑排序 */

void TopologicalSort(ALGraph G)

{ int i,k,count;ElemType e;ArcNode *p;

LinkQueue Q; /*定义队列*/

InitQueue(&Q);

for(i=0; i

if(!G.vexhead[i].indegree) EnQueue(&Q,i);

count=0; //对输出课程计数变量初始化

printf("\n\n\n以上课程的一个拓扑排序序列为:\n");

while(!QueueEmpty(Q))

{ DeQueue(&Q,&e); //先将入度为零的课程输出

printf("%s ",G.vexhead[e].name);

count++; //对输出的顶点计数

for(p=G.vexhead[e].firstarc;p;p=p->next) //遍历当前课程的邻接点

{ k=p->vexpos; //邻接点位置

if(!(--G.vexhead[k].indegree)) //每个邻接点入度减1后若为零则入队列EnQueue(&Q,k);

}

}

printf("\n");

if(count

{ printf("\n该有向图有回路,无法完成拓扑排序!\n"); }

}

/**********************************/

/* 以下为拓扑检测算法 */

/**********************************/

/* 11.运用拓扑排序的思想检测教学计划 */

void TopSortCheck(ALGraph G)

{ int i,k; ArcNode *p; VertexType v,CheckList[12];//待检测序列

TopologicalSort(G);

printf("\n输入待检测的课程序列:\n");

for(i=0; i

scanf("%s",CheckList[i]);

for(i=0; i

{ strcpy(v,CheckList[i]);

k=LocateVex(G,v);

if(k>=G.vexnum) //判断课程是否存在

{ printf("课程%s不存在!\n",v);return; }

if(G.vexhead[k].indegree!=0) //判断课程入度是否为零

{ printf("学习课程%s时,还有%d门先决课程未学!\n",v,G.vexhead[k].indegree);

printf("本课程序列不是拓扑序列\n\n");return; }

else

{ for(p=G.vexhead[LocateVex(G,v)].firstarc;p;p=p->next)//遍历此课程邻接点{ k=p->vexpos; //邻接点位置

G.vexhead[k].indegree--;} //每个邻接点入度减1

}

}

printf("本课程序列符合拓扑序列\n\n");

}

/*******************************************/

/* 12.主函数 */

/*******************************************/

void main()

{ ALGraph G; int menu,menu2;

while(1){

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

printf(" * 1.建立有向图并输出 *\n");

printf(" * 2.建立有向图并求一个拓扑排序序列 *\n");

printf(" * 3.检测用户输入的课程安排 *\n");

printf(" * 4.清屏 *\n");

printf(" * 5.退出 *\n");

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

printf(" 请输入你的选择:");

scanf("%d",&menu);

switch(menu){

case 1:

if(CreateGraph(&G)){system("PAUSE");PrintGraph(G);}//有向图建成则执操作

break;

case 2:

if(CreateGraph(&G)) //有向图建成则执操作

{ system("PAUSE");

PrintGraph(G);system("PAUSE");

TopologicalSort(G); }

break;

case 3:

if(CreateGraph2(&G)){ //有向图建成则执操作

system("PAUSE");

PrintGraph2(G); system("PAUSE");

while(1){

TopSortCheck(G);

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

printf(" * 1.检测其他课程序列 *\n");

printf(" * 2.完成检测 *\n");

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

printf(" 请输入你的选择:");

scanf("%d",&menu2);

if(menu2!=1) break; }

}

break;

case 4:

system("CLS");

break;

case 5:

return;

}

}

}

七、测试数据

1、对“建立有向图并输出”的测试

1) 正确的有向图信息

顶点数和弧数:4,3

顶点:A B C D

边: A B B C C D

2) 错误的边

顶点数和弧数:4,3

顶点:A B C D

边: A B B C C E

3) 错误的顶点数或弧数

顶点数和弧数:3,7

2、对“建立有向图并求一个拓扑排序序列”的测试

1) 有向图能实现拓扑排序

顶点数和弧数:5,5

顶点:A B C D E

边:A D D C C B E A E C

2) 有向图不能实现拓扑排序

顶点数和弧数:5,5

顶点:A B C D E

边:A D D C C B E A B A

3、对“检测用户输入的课程安排”的测试

1) 课程序列符合拓扑序列

课程序列:C9 C10 C11 C6 C1 C12 C4 C2 C3 C5 C7 C8

2) 课程序列中有课程不存在

课程序列:C9 C10 C11 C6 C1 C12 C4 C2 C13 C5 C7 C8

3) 课程序列不是拓扑序列

课程序列:C9 C10 C11 C1 C8 C6 C12 C4 C2 C3 C5 C7

八、测试情况

程序初始执行界面(以下测试编号与本文第七节测试数据编号一一对应)

1、对“建立有向图并输出”的测试

1) 正确的有向图信息

有向图信息正确的情况下,程序显示“有向图建立成功”,并输出有向图。

2) 错误的边

本测试中,第三条边(C E)的一个顶点E不是有向图中的顶点,程序能判断本错误并显示相应的提示信息。

3) 错误的顶点数或弧数

本测试中,顶点数和弧数分别为3,7。若有向图共有n个顶点,两顶点间最多有2条有向边,则有向图最多有n*(n-1)条边。而3*(3-1)=6<7,故程序提示“顶点数或弧数不正确,有向图建立失败”;程序还能判断负的顶点数和弧数。

2、对“建立有向图并求一个拓扑排序序列”的测试

1) 有向图能实现拓扑排序

有向图能实现拓扑排序的情况下,程序输出其中一个拓扑排序序列。

2) 有向图不能实现拓扑排序

本测试中,有向图其中四条边(A D)、(D C)、(C B)、(B A)构成环,程序能判断有向图有回路并提示相应信息。

3、对“检测用户输入的课程安排”的测试

程序首先输出预置的课程信息和据此建立的有向图。

1) 课程序列符合拓扑序列

在用户输入的课程序列符合拓扑序列的情况下,程序提示“本课程序列符合拓扑序列”,并显示如图菜单。

2) 课程序列中有课程不存在

本程序预置了C1-C12共12门课程,若用户输入的课程序列中有不属于预置课程的课程,程序会提示“课程XX不存在!”,并显示如图菜单。

3) 课程序列不是拓扑序列

若用户输入的课程序列不是拓扑序列,程序会输出原因,即“学习课程XX时,还有X门先决课程未学!”,并显示如图菜单。

九、参考文献

1、严蔚敏,《数据结构( C语言版)》,清华大学出版社。

2、谭浩强,《C语言程序设计》,清华大学出版社。

小结

平时我就比较爱好编程,有时候自己也会设想一些小程序,然后通过自己的努力来实现。因此我把本次课程设计当作了又一次锻炼,拿到题目后,经过与组员的讨论便开始了程序的编写。

大家都知道,编程是一件很需要耐心的事。因为几乎每一个程序的编写,都需要学习新的知识才能进行,同时程序调试过程很枯燥,有时候一点小错意味着长时间的查错。如语法错误中,“;”丢失、“{”与“}”不匹配等问题最难定位到出错语句;逻辑错误中,作为循环变量的“i”与“j”相互混淆、对未分配空间的节点进行操作等,都会使程序运行出错而难以找到原因。算法设计、程序调试的过程中,经常遇到看似简单但又无法解决的问题,这时候很容易灰心丧气,此时切不可烦躁,一定要冷静的思考,认真的分析;而解决问题,完成程序后,那种兴奋感与成就感也令人振奋。可以说编写程序既是一件艰苦的工作,又是一件愉快的事情。

我的小组课程设计题目的核心是“拓扑排序”。虽然平时对拓扑排序有一些了解,上课也学过,但真正应用到程序中,写出算法却一点也不简单。拓扑排序,首先需要有被排序的主体,也就是有向图,于是先要实现有向图的建立及相关操作;有向图的建立,该选取怎样的数据结构,是邻接矩阵还是邻接表,本着尽量靠近实际应用的态度,我选择了节省存储空间的邻接表;拓扑排序要将图中零入度顶点先输出,可利用栈或队列实现,而本程序的一个应用是实现教学计划的安排,考虑到教学计划安排的实际情况,一般先学各门基础课(入度为零),再学专业课(入度不为零),与队列先进先出的特点相符,故采用队列实现。总之,什么地方该用什么数据结构,该写出怎样的算法,都要经过精心分析和仔细考虑。

课程设计不是一个人的任务,而是一个小组三个成员共同的任务,不但要能完成程序,而且在完成的过程中也要让团队有效地协作起来。在本次课程设计的过程中,我认识到以下几点:第一,要有奉献精神,不要怕自己多做了,不要怕自己承担的任务有多重,而其他成员做的很少。多去做一点不会吃亏,还能学到更多的东西。团队成员之间应团结互助,不计功过得失;第二,分工上不能马虎,要具体到个人,每个人负责哪部分任务,什么时候完成,都要有明确的说明,应各尽其能,做到资源优化配置;第三,具体工作时,各成员应频繁交流,避免各自为政,最后导致函数功能不符要求,参数调用不方便,或是论文作者无从下手;第四,当工作出现问题时,各成员应仔细商讨,尽快找到问题的症结,决不应推卸责任,更不能相互埋怨。

在完成课程设计的过程中,我加深了对程序结构的了解程度,对各种语句理解也更透彻,学会了灵活运用。同时体会到了团队合作的乐趣,一向惯于“独立思考”的我们学会了积极地同团队成员交流,取长补短,共同进步,只有和同学多交流多学习才能不断地提高自身水平。

总之,这学期的数据结构课程设计,让我们学到了很多,受益匪浅。

大数据结构拓扑排序实验报告材料

拓扑排序 [基本要求] 用邻接表建立一个有向图的存储结构。利用拓扑排序算法输出该图的拓扑排序序列。 [编程思路] 首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意有向是不需要对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,几乎和图的创建一样,图的顶点定义时加入int indegree,关键在于indegree 的计算,而最好的就是在创建的时候就算出入度,(没有采用书上的indegree【】数组的方法,那样会增加一个indegree算法,而是在创建的时候假如一句计数的代码(G.vertices[j].indegree)++;)最后调用拓扑排序的算法,得出拓扑序列。 [程序代码] 头文件: #define MAX_VERTEX_NUM 30 #define STACKSIZE 30 #define STACKINCREMENT 10 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define TRUE 1 #define FALSE 0 typedef int Status; typedef int InfoType; typedef int Status; typedef int SElemType; /* 定义弧的结构*/ typedef struct ArcNode{ int adjvex; /*该边所指向的顶点的位置*/ struct ArcNode *nextarc; /*指向下一条边的指针*/ InfoType info; /*该弧相关信息的指针*/

数据结构课程设计(内部排序算法比较_C语言)

数据结构课程设计 课程名称:内部排序算法比较 年级/院系:11级计算机科学与技术学院 姓名/学号: 指导老师: 第一章问题描述 排序是数据结构中重要的一个部分,也是在实际开发中易遇到的问题,所以研究各种排算法的时间消耗对于在实际应用当中很有必要通过分析实际结合算法的特性进行选择和使用哪种算法可以使实际问题得到更好更充分的解决!该系统通过对各种内部排序算法如直接插入排序,冒泡排序,简单选择排序,快速排序,希尔排序,堆排序、二路归并排序等,以关键码的比较次数和移动次数分析其特点,并进行比较,估算每种算法的时间消耗,从而比较各种算法的优劣和使用情况!排序表的数据是多种不同的情况,如随机产生数据、极端的数据如已是正序或逆序数据。比较的结果用一个直方图表示。

第二章系统分析 界面的设计如图所示: |******************************| |-------欢迎使用---------| |-----(1)随机取数-------| |-----(2)自行输入-------| |-----(0)退出使用-------| |******************************| 请选择操作方式: 如上图所示该系统的功能有: (1):选择1 时系统由客户输入要进行测试的元素个数由电脑随机选取数字进行各种排序结果得到准确的比较和移动次数并 打印出结果。 (2)选择2 时系统由客户自己输入要进行测试的元素进行各种排序结果得到准确的比较和移动次数并打印出结果。 (3)选择0 打印“谢谢使用!!”退出系统的使用!! 第三章系统设计 (I)友好的人机界面设计:(如图3.1所示) |******************************| |-------欢迎使用---------| |-----(1)随机取数-------| |-----(2)自行输入-------| |-----(0)退出使用-------|

数据结构课程设计

1.一元稀疏多项式计算器 [问题描述] 设计一个一元稀疏多项式简单计算器。 [基本要求] 输入并建立多项式; 输出多项式,输出形式为整数序列:n, c1, e1, c2, e2,……, cn, en ,其中n是多项式的项数,ci, ei分别是第i项的系数和指数,序列按指数降序排序; 多项式a和b相加,建立多项式a+b; 多项式a和b相减,建立多项式a-b; [测试数据] (2x+5x8-3.1x11)+(7-5x8+11x9)=(-3.1x11+11x9+2x+7) (6x-3-x+4.4x2-1.2x9)-(-6x-3+5.4x2-x2+7.8x15)=(-7.8x15-1.2x9-x+12x-3) (1+x+x2+x3+x4+x5)+(-x3-x4)=(x5+x2+x+1) (x+x3)+(-x-x3)=0 (x+x2+x3)+0=(x3+x2+x) [实现提示] 用带头结点的单链表存储多项式,多项式的项数存放在头结点中。 2.背包问题的求解 [问题描述] 假设有一个能装入总体积为T的背包和n件体积分别为w1, w2, …,wn的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+…+wn=T,要求找出所有满足上述条件的解。例如:当T=10,各件物品的体积为{1,8,4,3,5,2}时,可找到下列4组解:(1,4,3,2)、(1,4,5)、(8,2)、(3,5,2) [实现提示] 可利用回溯法的设计思想来解决背包问题。首先,将物品排成一列,然后顺序选取物品转入背包,假设已选取了前i件物品之后背包还没有装满,则继续选取第i+1件物品,若该件物品“太大”不能装入,则弃之而继续选取下一件,直至背包装满为止。但如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入背包的那件物品“不合适”,应将它取出“弃之一边”,继续再从“它之后”的物品中选取,如此重复,直至求得满足条件的解,或者无解。 由于回溯求解的规则是“后进先出”因此自然要用到栈。 3.完全二叉树判断 用一个二叉链表存储的二叉树,判断其是否是完全二叉树。 4.最小生成树求解(1人) 任意创建一个图,利用克鲁斯卡尔算法,求出该图的最小生成树。 5.最小生成树求解(1人) 任意创建一个图,利用普里姆算法,求出该图的最小生成树。 6.树状显示二叉树 编写函数displaytree(二叉树的根指针,数据值宽度,屏幕的宽度)输出树的直观示意图。输出的二叉树是垂直打印的,同层的节点在同一行上。 [问题描述] 假设数据宽度datawidth=2,而屏幕宽度screenwidth为64=26,假设节点的输出位置用 (层号,须打印的空格数)来界定。 第0层:根在(0,32)处输出;

算法排序问题实验报告

《排序问题求解》实验报告 一、算法的基本思想 1、直接插入排序算法思想 直接插入排序的基本思想是将一个记录插入到已排好序的序列中,从而得到一个新的,记录数增1 的有序序列。 直接插入排序算法的伪代码称为InsertionSort,它的参数是一个数组A[1..n],包含了n 个待排序的数。用伪代码表示直接插入排序算法如下: InsertionSort (A) for i←2 to n do key←A[i] //key 表示待插入数 //Insert A[i] into the sorted sequence A[1..i-1] j←i-1 while j>0 and A[j]>key do A[j+1]←A[j] j←j-1 A[j+1]←key 2、快速排序算法思想 快速排序算法的基本思想是,通过一趟排序将待排序序列分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可对这两部分记录继续进行排序,以达到整个序列有序。 假设待排序序列为数组A[1..n],首先选取第一个数A[0],作为枢轴(pivot),然后按照下述原则重新排列其余数:将所有比A[0]大的数都排在它的位置之前,将所有比A[0] 小的数都排在它的位置之后,由此以A[0]最后所在的位置i 作为分界线,将数组A[1..n]分成两个子数组A[1..i-1]和A[i+1..n]。这个过程称作一趟快速排序。通过递归调用快速排序,对子数组A[1..i-1]和A[i+1..n]排序。 一趟快速排序算法的伪代码称为Partition,它的参数是一个数组A[1..n]和两个指针low、high,设枢轴为pivotkey,则首先从high 所指位置起向前搜索,找到第一个小于pivotkey 的数,并将其移到低端,然后从low 所指位置起向后搜索,找到第一个大于pivotkey 的数,并将其移到高端,重复这两步直至low=high。最后,将枢轴移到正确的位置上。用伪代码表示一趟快速排序算法如下: Partition ( A, low, high) A[0]←A[low] //用数组的第一个记录做枢轴记录 privotkey←A[low] //枢轴记录关键字 while low=privotkey do high←high-1 A[low]←A[high] //将比枢轴记录小的记录移到低端 while low

实验报告

算法与数据结构 实验报告 系(院):计算机科学学院 专业班级:软工11102 姓名:潘香杰 学号: 201104449 班级序号: 18 指导教师:詹泽梅老师 实验时间:2013.6.17 - 2013.6.29 实验地点:4号楼5楼机房

目录 1、课程设计目的...................................... 2、设计任务.......................................... 3、设计方案.......................................... 4、实现过程.......................................... 5、测试.............................................. 6、使用说明.......................................... 7、难点与收获........................................ 8、实现代码.......................................... 9、可改进的地方.....................................

算法与数据结构课程设计是在学完数据结构课程之后的实践教学环节。本实践教学是培养学生数据抽象能力,进行复杂程序设计的训练过程。要求学生能对所涉及问题选择合适的数据结构、存储结构及算法,并编写出结构清楚且正确易读的程序,提高程序设计基本技能和技巧。 一.设计目的 1.提高数据抽象能力。根据实际问题,能利用数据结构理论课中所学到的知识选择合适的逻辑结构以及存储结构,并设计出有效解决问题的算法。 2.提高程序设计和调试能力。学生通过上机实习,验证自己设计的算法的正确性。学会有效利用基本调试方法,迅速找出程序代码中的错误并且修改。 3.初步了解开发过程中问题分析、整体设计、程序编码、测试等基本方法和技能。二.设计任务 设计一个基于DOS菜单的应用程序。要利用多级菜单实现各种功能。内容如下: ①创建无向图的邻接表 ②无向图的深度优先遍历 ③无向创建无向图的邻接矩阵 ④无向图的基本操作及应用 ⑤图的广度优先遍历 1.有向图的基本操作及应用 ①创建有向图的邻接矩阵 ②创建有向图的邻接表 ③拓扑排序 2.无向网的基本操作及应用 ①创建无向网的邻接矩阵 ②创建无向网的邻接表 ③求最小生成树 3.有向网的基本操作及应用 ①创建有向网的邻接矩阵 ②创建有向网的邻接表 ③关键路径 ④单源最短路径 三.设计方案 第一步:根据设计任务,设计DOS菜单,菜单运行成果如图所示:

《数据结构与算法分析》课程设计:顺序表、单链表、顺序栈、查找、排序算法

*******大学 《数据结构与算法分析》课程设计 题目:数据结构上机试题 学生姓名: 学号: 专业:信息管理与信息系统 班级: 指导教师: 2014年04月

目录 一、顺序表的操作 (2) 【插入操作原理】 (2) 【删除操作原理】 (2) 【NO.1代码】 (3) 【运行截图演示】 (7) 二、单链表的操作 (10) 【创建操作原理】 (10) 【插入操作原理】 (10) 【删除操作原理】 (10) 【NO.2代码】 (11) 【运行截图演示】 (20) 三、顺序栈的操作 (25) 【数值转换原理】 (25) 【NO.3代码】 (26) 【运行截图演示】 (30) 四、查找算法 (32) 【顺序查找原理】 (32) 【折半查找原理】 (32) 【NO.4代码】 (33) 【运行截图演示】 (38) 五、排序算法 (40) 【直接插入排序原理】 (40) 【快速排序原理】 (40) 【NO.5代码】 (41) 【运行截图演示】 (46)

一、顺序表的操作 (1)插入元素操作:将新元素x 插入到顺序表a 中第i 个位置; (2)删除元素操作:删除顺序表a 中第i 个元素。 【插入操作原理】 线性表的插入操作是指在线性表的第i-1个数据元素和第i 个数据元素之间插入一个新的数据元素,就是要是长度为n 的线性表: ()11,,,,,i i n a a a a -………… 变成长度为n+1的线性表: ()11,,,,,,i i n a a b a a -………… 数据元素1i a -和i a 之间的逻辑关系发生了变化。 (其【插入原理】在课本P23的算法2.3有解释) 【删除操作原理】 反之,线性表的删除操作是使长度为n 的线性表: ()111,,,,,,i i i n a a a a a -+………… 变成长度为n-1的线性表: ()111,,,,,i i n a a a a -+………… 数据元素1i a -、i a 和1i a +之间的逻辑关系发生变化,为了在存储结构上放映这个变化,同样需要移动元素。 (其【删除原理】在课本P24的算法2.4有解释)

数据结构课程设计报告---几种排序算法的演示(附源代码)

? & 数据结构课程设计报告 —几种排序算法的演示( ; 时间:2010-1-14 … 一需求分析

运行环境 Microsoft Visual Studio 2005 程序所实现的功能 对直接插入排序、折半插入排序、冒泡排序、简单选择排序、快速排序、堆排序、归并排序算法的演示,并且输出每一趟的排序情况。 程序的输入(包含输入的数据格式和说明) % <1>排序种类三输入 <2>排序数的个数的输入 <3>所需排序的所有数的输入 程序的输出(程序输出的形式) <1>主菜单的输出 <2>每一趟排序的输出,即排序过程的输出 " 二设计说明 算法设计思想 <1>交换排序(冒泡排序、快速排序) 交换排序的基本思想是:对排序表中的数据元素按关键字进行两两比较,如果发生逆序(即排列顺序与排序后的次序正好相反),则两者交换位置,直到所有数据元素都排好序为止。 <2>插入排序(直接插入排序、折半插入排序) % 插入排序的基本思想是:每一次设法把一个数据元素插入到已经排序的部分序列的合适位置,使得插入后的序列仍然是有序的。开始时建立一个初始的有序序列,它只包含一个数据元素。然后,从这个初始序列出发不断插入数据元素,直到最后一个数据元素插到有序序列后,整个排序工作就完成了。 <3>选择排序(简单选择排序、堆排序) 选择排序的基本思想是:第一趟在有n个数据元素的排序表中选出关键字最小的数据元素,然后在剩下的n-1个数据元素中再选出关键字最小(整个数据表中次小)的数据元素,依次重复,每一趟(例如第i趟,i=1,…,n-1)总是在当前剩下的n-i+1个待排序数据元素中选出关键字最小的数据元素,作为有序数据元素序列的第i个数据元素。等到第n-1趟选择结束,待排序数据元素仅剩下一个时就不用再选了,按选出的先后次序所得到的数据元素序列即为有序序列,排序即告完成。 <4>归并排序(两路归并排序) 两路归并排序的基本思想是:假设初始排序表有n个数据元素,首先把它看成是长度为

离散数学实验报告四个实验

《离散数学》 课程设计 学院计算机学院 学生姓名 学号 指导教师 评阅意见

提交日期 2011 年 11 月 25 日 引言 《离散数学》是现代数学的一个重要分支,也是计算机科学与技术,电子信息技术,生物技术等的核心基础课程。它是研究离散量(如整数、有理数、有限字母表等)的数学结构、性质及关系的学问。它一方面充分地描述了计算机科学离散性的特点,为学生进一步学习算法与数据结构、程序设计语言、操作系统、编译原理、电路设计、软件工程与方法学、数据库与信息检索系统、人工智能、网络、计算机图形学等专业课打好数学基础;另一方面,通过学习离散数学课程,学生在获得离散问题建模、离散数学理论、计算机求解方法和技术知识的同时,还可以培养和提高抽象思维能力和严密的逻辑推理能力,为今后爱念族皮及用计算机处理大量的日常事务和科研项目、从事计算机科学和应用打下坚实基础。特别是对于那些从事计算机科学与理论研究的高层次计算机人员来说,离散数学更是必不可少的基础理论工具。 实验一、编程判断一个二元关系的性质(是否具有自反性、反自反性、对称性、反对称性和传递性) 一、前言引语:二元关系是离散数学中重要的内容。因为事物之间总是可以根据需要确定相应的关系。从数学的角度来看,这类联系就是某个集合中元素之

间存在的关系。 二、数学原理:自反、对称、传递关系 设A和B都是已知的集合,R是A到B的一个确定的二元关系,那么集合R 就是A×B的一个合于{()∈A×}的子集合 设R是集合A上的二元关系: 自反关系:对任意的x∈A,都满足<>∈R,则称R是自反的,或称R具有自反性,即R在A上是自反的?(?x)((x∈A)→(<>∈R))=1 对称关系:对任意的∈A,如果<>∈R,那么<>∈R,则称关系R是对称的,或称R具有对称性,即R在A上是对称的? (?x)(?y)((x∈A)∧(y∈A)∧(<>∈R)→(<>∈R))=1 传递关系:对任意的∈A,如果<>∈R且<>∈R,那么<>∈R,则称关系R是传递的,或称R具有传递性,即R在A上是传递的? (?x)(?y)(?z)[(x∈A)∧(y∈A)∧(z ∈A)∧((<>∈R)∧(<>∈R)→(<>∈R))]=1 三、实验原理:通过二元关系与关系矩阵的联系,可以引入N维数组,以数组的运算来实现二元关系的判断。 图示:

排序算法课程设计

排序算法课程设计 专业 班级 学号 姓名 指导老师

一:课程设计的目的 1.掌握各种排序的基本思想 2.掌握各种排序的算法实现 3.掌握各种排序的算法优劣分析花费的时间计算 4.掌握各种排序算法所适用的不同场合。 二:课程设计的内容 (1)冒泡、直插、选择、快速、希尔、归并、堆排序算法进行比较; (2)待排序的元素的关键字为整数。其中的数据用伪随机产生程序产生(如10000个,1000个),再使用各种算法对其进行排序,记录其排序时间,再汇总比较;(3)将每次测试所用的时间,用条形图进行表示,以便比较各种排序的优劣。 三:课程设计的实现 (1)直接插入排序 #include typedef int keytype; struct datatype { keytype key; }; /* int rand(void); void srand(unsigned int seed ); */ #include #include #include #include void InsertSort (datatype a[], int n) //用直接插入法对a[0]--a[n-1]排序 { int i, j; datatype temp; for(i=0; i

while(j > -1 && temp.key <= a[j].key) { a[j+1] = a[j]; j--; } a[j+1] = temp; } } void main() { /*srand((unsigned)time(NULL));// 随机种子*/ /*time_t t; srand((unsigned)time(&t));*/ time_t t1,t2; srand((unsigned)GetCurrentTime()); datatype num[10000]; t1=GetCurrentTime(); for(int i=0;i<10000;i++) { num[i].key=rand(); } int n=10000; InsertSort(num,n); for(int j=0;j<10000;j++) cout< /* int rand(void); void srand(unsigned int seed ); */ #include #include #include #include typedef int keytype; struct datatype { keytype key;

数据结构课程设计-排序

一、问题描述 1、排序问题描述 排序是计算机程序设计的一种重要操作,他的功能是将一组任意顺序数据元素(记录),根据某一个(或几个)关键字按一定的顺序重新排列成为有序的序列。简单地说,就是将一组“无序”的记录序列调整为“有序”的记录序列的一种操作。 本次课程设计主要涉及几种常用的排序方法,分析了排序的实质,排序的应用,排序的分类,同时进行各排序方法的效率比较,包括比较次数和交换次数。我们利用java语言来实现本排序综合系统,该系统包含了:插入排序、交换排序、选择排序、归并排序。其中包括: (1)插入排序的有关算法:不带监视哨的直接插入排序的实现; (2)交换排序有关算法:冒泡排序、快速排序的实现; (3)选择排序的有关算法:直接选择排序、堆排序的实现; (4)归并排序的有关算法:2-路归并排序的实现。 2、界面设计模块问题描述 设计一个菜单式界面,让用户可以选择要解决的问题,同时可以退出程序。界面要求简洁明了,大方得体,便于用户的使用,同时,对于用户的错误选择可以进行有效的处理。 二、问题分析 本人设计的是交换排序,它的基本思想是两两比较带排序记录的关键字,若两个记录的次序相反则交换这两个记录,直到没有反序的记录为止。应用交换排序基本思想的主要排序方法有冒泡排序和快速排序。 冒泡排序的基本思想是:将待排序的数组看作从上到下排列,把关键字值较小的记录看作“较轻的”,关键字值较大的纪录看作“较重的”,较小关键字值的记录好像水中的气泡一样,向上浮;较大关键字值的纪录如水中的石块向下沉,当所有的气泡都浮到了相应的位置,并且所有的石块都沉到了水中,排序就结束了。 冒泡排序的步骤: 1)置初值i=1; 2)在无序序列{r[0],r[1],…,r[n-i]}中,从头至尾依次比较相邻的两个记录r[j] 与r[j+1](0<=j<=n-i-1),若r[j].key>r[j+1].key,则交换位置; 3)i=i+1; 4)重复步骤2)和3),直到步骤2)中未发生记录交换或i=n-1为止; 要实现上述步骤,需要引入一个布尔变量flag,用来标记相邻记录是否发生交换。 快速排序的基本思想是:通过一趟排序将要排序的记录分割成独立的两个部分,其中一部分的所有记录的关键字值都比另外一部分的所有记录关键字值小,然后再按此方法对这两部分记录分别进行快速排序,整个排序过程可以递归进行,以此达到整个记录序列变成有序。 快速排序步骤: 1)设置两个变量i、j,初值分别为low和high,分别表示待排序序列的起始下

数据结构课程设计排序算法总结

排序算法: (1) 直接插入排序 (2) 折半插入排序(3) 冒泡排序 (4) 简单选择排序 (5) 快速排序(6) 堆排序 (7) 归并排序 【算法分析】 (1)直接插入排序;它是一种最简单的排序方法,它的基本操作是将一个记录插入到已排好的序的有序表中,从而得到一个新的、记录数增加1的有序表。 (2)折半插入排序:插入排序的基本操作是在一个有序表中进行查找和插入,我们知道这个查找操作可以利用折半查找来实现,由此进行的插入排序称之为折半插入排序。折半插入排序所需附加存储空间和直接插入相同,从时间上比较,折半插入排序仅减少了关键字间的比较次数,而记录的移动次数不变。 (3)冒泡排序:比较相邻关键字,若为逆序(非递增),则交换,最终将最大的记录放到最后一个记录的位置上,此为第一趟冒泡排序;对前n-1记录重复上操作,确定倒数第二个位置记录;……以此类推,直至的到一个递增的表。 (4)简单选择排序:通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换之。 (5)快速排序:它是对冒泡排序的一种改进,基本思想是,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 (6)堆排序: 使记录序列按关键字非递减有序排列,在堆排序的算法中先建一个“大顶堆”,即先选得一个关键字为最大的记录并与序列中最后一个记录交换,然后对序列中前n-1记录进行筛选,重新将它调整为一个“大顶堆”,如此反复直至排序结束。 (7)归并排序:归并的含义是将两个或两个以上的有序表组合成一个新的有序表。假设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列;再两两归并,……,如此重复,直至得到一个长度为n的有序序列为止,这种排序称为2-路归并排序。 【算法实现】 (1)直接插入排序: void InsertSort(SqList &L){ for(i=2;i<=L.length ;i++) if(L.elem[i]L.elem[0];j--) L.elem [j+1]=L.elem [j]; L.elem [j+1]=L.elem[0]; } } (2)折半插入排序:

数据结构课程设计(内部排序算法比较 C语言)

课题:内部排序算法比较 第一章问题描述 排序是数据结构中重要的一个部分,也是在实际开发中易遇到的问题,所以研究各种排算法的时间消耗对于在实际应用当中很有必要通过分析实际结合算法的特性进行选择和使用哪种算法可以使实际问题得到更好更充分的解决!该系统通过对各种内部排序算法如直接插入排序,冒泡排序,简单选择排序,快速排序,希尔排序,堆排序、二路归并排序等,以关键码的比较次数和移动次数分析其特点,并进行比较,估算每种算法的时间消耗,从而比较各种算法的优劣和使用情况!排序表的数据是多种不同的情况,如随机产生数据、极端的数据如已是正序或逆序数据。比较的结果用一个直方图表示。 第二章系统分析 界面的设计如图所示: |******************************| |-------欢迎使用---------| |-----(1)随机取数-------|

|-----(2)自行输入-------| |-----(0)退出使用-------| |******************************| 请选择操作方式: 如上图所示该系统的功能有: (1):选择 1 时系统由客户输入要进行测试的元素个数由电脑随机选取数字进行各种排序结果得到准确的比较和移动次数并打印出结果。 (2)选择 2 时系统由客户自己输入要进行测试的元素进行各种排序结果得到准确的比较和移动次数并打印出结果。 (3)选择0 打印“谢谢使用!!”退出系统的使用!! 第三章系统设计 (I)友好的人机界面设计:(如图3.1所示) |******************************| |-------欢迎使用---------| |-----(1)随机取数-------| |-----(2)自行输入-------| |-----(0)退出使用-------| |******************************| (3.1) (II)方便快捷的操作:用户只需要根据不同的需要在界面上输入系统提醒的操作形式直接进行相应的操作方式即可!如图(3.2所示) |******************************| |-------欢迎使用---------| |-----(1)随机取数-------| |-----(2)自行输入-------| |-----(0)退出使用-------|

数据结构课程设计排序实验报告

《数据结构》课程设计报告 专业 班级 姓名 学号 指导教师 起止时间

课程设计:排序综合 一、任务描述 利用随机函数产生n个随机整数(20000以上),对这些数进行多种方法进行排序。(1)至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。并把排序后的结果保存在不同的文件中。 (2)统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。 要求:根据以上任务说明,设计程序完成功能。 二、问题分析 1、功能分析 分析设计课题的要求,要求编程实现以下功能: (1)随机生成N个整数,存放到线性表中; (2)起泡排序并计算所需时间; (3)简单选择排序并计算时间; (4)希尔排序并计算时间; (5)直接插入排序并计算所需时间; (6)时间效率比较。 2、数据对象分析 存储数据的线性表应为顺序存储。 三、数据结构设计 使用顺序表实现,有关定义如下: typedef int Status; typedef int KeyType ; //设排序码为整型量 typedef int InfoType; typedef struct { //定义被排序记录结构类型 KeyType key ; //排序码 I nfoType otherinfo; //其它数据项 } RedType ; typedef struct { RedType * r; //存储带排序记录的顺序表 //r[0]作哨兵或缓冲区 int length ; //顺序表的长度 } SqList ; //定义顺序表类型 四、功能设计 (一)主控菜单设计

数据结构课程设计报告---几种排序算法的演示(附源代码)

数据结构课程设计报告 —几种排序算法的演示 时间:2010-1-14 一需求分析 运行环境 Microsoft Visual Studio 2005

程序所实现的功能 对直接插入排序、折半插入排序、冒泡排序、简单选择排序、快速排序、堆排序、归并排序算法的演示,并且输出每一趟的排序情况。 程序的输入(包含输入的数据格式和说明) <1>排序种类三输入 <2>排序数的个数的输入 <3>所需排序的所有数的输入 程序的输出(程序输出的形式) <1>主菜单的输出 <2>每一趟排序的输出,即排序过程的输出 二设计说明 算法设计思想 <1>交换排序(冒泡排序、快速排序) 交换排序的基本思想是:对排序表中的数据元素按关键字进行两两比较,如果发生逆序(即排列顺序与排序后的次序正好相反),则两者交换位置,直到所有数据元素都排好序为止。 <2>插入排序(直接插入排序、折半插入排序) 插入排序的基本思想是:每一次设法把一个数据元素插入到已经排序的部分序列的合适位置,使得插入后的序列仍然是有序的。开始时建立一个初始的有序序列,它只包含一个数据元素。然后,从这个初始序列出发不断插入数据元素,直到最后一个数据元素插到有序序列后,整个排序工作就完成了。 <3>选择排序(简单选择排序、堆排序)

选择排序的基本思想是:第一趟在有n个数据元素的排序表中选出关键字最小的数据元素,然后在剩下的n-1个数据元素中再选出关键字最小(整个数据表中次小)的数据元素,依次重复,每一趟(例如第i趟,i=1,…,n-1)总是在当前剩下的n-i+1个待排序数据元素中选出关键字最小的数据元素,作为有序数据元素序列的第i个数据元素。等到第n-1趟选择结束,待排序数据元素仅剩下一个时就不用再选了,按选出的先后次序所得到的数据元素序列即为有序序列,排序即告完成。 <4>归并排序(两路归并排序) 两路归并排序的基本思想是:假设初始排序表有n个数据元素,首先把它看成是长度为1的首尾相接的n个有序子表(以后称它们为归并项),先做两两归并,得n/2上取整个长度为2的归并项(如果n为奇数,则最后一个归并项的长度为1);再做两两归并,……,如此重复,最后得到一个长度为n的有序序列。 程序的主要流程图

图的应用的实验报告

实验六图的应用及其实现 一、实验目的 1.进一步功固图常用的存储结构。 2.熟练掌握在图的邻接表实现图的基本操作。 3.理解掌握AOV网、AOE网在邻接表上的实现以及解决简单的应用问题。 二、实验内容 [题目一]:从键盘上输入AOV网的顶点和有向边的信息,建立其邻接表存储结构,然后对该图拓扑排序,并输出拓扑序列. 试设计程序实现上述AOV网的类型定义和基本操作,完成上述功能。 测试数据:教材图7.28 [题目二]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。 测试数据:教材图7.29 三、实验步骤 ㈠、数据结构与核心算法的设计描述 基本数据结构: #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 typedef int Status; /* Status 是函数的类型,其值是函数结果状态代码,如OK 等*/ #define INFINITY INT_MAX //定义无穷大∞ #define MAX_VERTEX_NUM 20 typedef int V ertexType; typedef int InfoType; typedef struct ArcNode // 表结点定义 { InfoType info; int adjvex; //邻接点域,存放与V i邻接的点在表头数组中的位置ArcNode *nextarc; //链域,指示依附于vi的下一条边或弧的结点, }ArcNode; typedef struct VNode //表头结点 { int data; //存放顶点信息 struct ArcNode *firstarc; //指示第一个邻接点 }VNode,AdjList[MAX_VERTEX_NUM]; typedef struct { //图的结构定义

数据结构 课程设计报告(排序算法比较)

数据结构课程设计报告 学院:计算机科学与工程 专业:计算机科学与技术 班级:09级班 学号: 姓名: 指导老师: 时间: 2010年12月

一、课程设计题目:1、哈夫曼编码的实现 2、城市辖区地铁线路设计 3、综合排序算法的比较 二、小组成员: 三、题目要求: 1.哈夫曼编码的实现 (1)打开若干篇英文文章,统计该文章中每个字符出现的次数,进一步统一各字符出现的概率。 (2)针对上述统计结果,对各字符实现哈夫曼编码 (3)对任意文章,用哈夫曼编码对其进行编码 (4)对任意文章,对收到的电文进行解码 2.某城市要在其各个辖区之间修建地铁来加快经济发展,但由于建设地铁的费用昂贵,因此需要合理安排地铁的建设路线。 (1)从包含各辖区的地图文件中读取辖区的名称和各辖区的直接距离 (2)根据上述读入的信息,给出一种铺设地铁线路的解决方案。使乘客可以沿地铁到达各个辖区,并使总的建设费用最小。 (3)输出应该建设的地铁路线及所需要建设的总里程信息。 3.综合排序算法的比较 各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概的执行时间。试通过随机的数据比较各算法的关键字比较次数和关键字移动的次数。 (1)对以下各种常用的内部排序算法进行比较: 直接插入排序,折半插入排序,二路归并排序,希尔排序,冒泡排序,快速排序,简单选择排序,堆排序,归并排序,基数排序。 (2)待排序的表长不少于100,要求采用随机数。 (3)至少要用5组不同的输入数据做比较:比较的次数为有关键字参加的比较次数和关键字移动的次数 (4)改变数据量的大小,观察统计数据的变化情况。 (5)对试验统计数据进行分析。对各类排序算法进行综合评价。 四、项目安排: 1、小组内分工合作 分工:负责哈夫曼编码的实现,负责城市辖区地铁线路设计,负责综合排序算法的比较。 合作:组内,组外进行交流,组长帮助解决组员的在项目过程中的困难,并控制进度。 五、完成自己的任务:

数据结构课程设计(附代码)

上海应用技术学院课程设计报告 课程名称《数据结构课程设计》 设计题目猴子选大王;建立二叉树;各种排序;有序表的合并;成绩管理系统;院系计算机科学与信息工程专业计算机科学与技术班级 姓名学号指导教师日期 一.目的与要求 1. 巩固和加深对常见数据结构的理解和掌握 2. 掌握基于数据结构进行算法设计的基本方法 3. 掌握用高级语言实现算法的基本技能 4. 掌握书写程序设计说明文档的能力 5. 提高运用数据结构知识及高级语言解决非数值实际问题的能力 二.课程设计内容说明 1. 项目一 (1) 对设计任务内容的概述 学生成绩管理** 任务:要求实现对学生资料的录入、浏览、插入和删除等功能。 输入:设学生成绩以记录形式存储,每个学生记录包含的信息有:学号和各门课程的成绩,设学生成绩至少3门以上。存储结构:采用线性链式结构。 (2) 详细设计 LinkList *create():输入学生成绩记录函数; void print(LinkList *head):显示全部记录函数 LinkList *Delete(LinkList *head):删除记录函数 LinkList *Insert(LinkList *head):插入记录函数 void menu_select():菜单选择 void ScoreManage():函数界面

(3) 程序流程图 (4) 程序模块及其接口描述 该程序可以分为以下几个模块: 1、菜单选择:void menu_select(); 提供五种可以选择的操作,在main函数中通过switch语句调用菜单menu_select()函数,进入不同的功能函数中完成相关操作。

几种排序算法的平均性能比较(实验报告)

实验课程:算法分析与设计 实验名称:几种排序算法的平均性能比较(验证型实验) 实验目标: (1)几种排序算法在平均情况下哪一个更快。 (2)加深对时间复杂度概念的理解。 实验任务: (1)实现几种排序算法(selectionsort, insertionsort,bottomupsort,quicksort, 堆排序)。对于快速分类,SPLIT中的划分元素采用三者A(low),A(high),A((low+high)/2)中其值居中者。(2)随机产生20组数据(比如n=5000i,1≤i≤20)。数据均属于围(0,105)的整数。对于同一组数据,运行以上几种排序算法,并记录各自的运行时间(以毫秒为单位)。 (3)根据实验数据及其结果来比较这几种分类算法的平均时间和比较次数,并得出结论。实验设备及环境: PC;C/C++等编程语言。 实验主要步骤: (1)明确实验目标和具体任务; (2)理解实验所涉及的几个分类算法; (3)编写程序实现上述分类算法; (4)设计实验数据并运行程序、记录运行的结果; (5)根据实验数据及其结果得出结论; (6)实验后的心得体会。 问题分析(包括问题描述、建模、算法的基本思想及程序实现的技巧等): 选择排序:令A[1…n]为待排序数组,利用归纳法,假设我们知道如何对后n-1个元素排序,即对啊[A…n]排序。对某个j,1<=j<=n,设A[j]是最小值。首先,如果就!=1,我们交换A[1]和A[j]。然后由假设,已知如何对A[2..n]排序,因此可对在A[2…n]中的元素递归地排序。可把递归改为迭代。算法程序实现如下: void SelectionSort(int *Array,int n,int &c) { int i,j,k; int aa; c=0; for(i=0;i

数据结构实验报告

《数据结构》实验报告 专业惠普测试 班级142 姓名李斌 学号1408090221 学期 3 指导老师刘勇

成绩: 教师评语: 数据结构上机实验报告 学号:1408090221 姓名:李斌所在系:惠普测试班级:142 实验名称:线性结构基本算法的实现实验日期 实验指导教师刘勇实验机房 ------------------------------------------------------------------------------------------------------

1.实验目的: (1)掌握线性表顺序存储结构的基本操作:插入、删除、查找; (2)掌握线性表链式结构的基本操作:插入、删除、合并等运算; (3)掌握栈和队列基本运算的算法; (4)掌握稀疏矩阵的压缩存储的算法。 2. 实验内容: (1)实现顺序表的创建、插入、删除和查找的操作; (2)实现单链表插入、删除、合并的操作; (3)实现2个有序线性表的合并; (4)利用顺序栈实现括号匹配的算法; (5)实现顺序队列各种基本运算的算法; (6)实现链栈各种基本运算的算法;(选做) (7)实现链队列各种基本运算的算法;(选做) (8)实现稀疏矩阵压缩存储的算法。 3.算法设计(编程思路或流程图或源代码) 内容: 1、顺序表的插入和删除 2、有序单链表的合并 3、数制转换的算法实现 1. //顺序表的插入和删除 #include //#include #include #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 #define TURE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1

相关文档
最新文档