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

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

拓扑排序

一、问题描述

在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”相互混淆、对未分配空间的节点进行操作等,都会使程序运行出错而难以找到原因。算法设计、程序调试的过程中,经常遇到看似简单但又无法解决的问题,这时候很容易灰心丧气,此时切不可烦躁,一定要冷静的思考,认真的分析;而解决问题,完成程序后,那种兴奋感与成就感也令人振奋。可以说编写程序既是一件艰苦的工作,又是一件愉快的事情。

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

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

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

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

数据结构课程设计

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)处输出;

数据结构课程设计报告模板

《数据结构I》三级项目报告 大连东软信息学院 电子工程系 ××××年××月

三级项目报告注意事项 1. 按照项目要求书写项目报告,条理清晰,数据准确; 2. 项目报告严禁抄袭,如发现抄袭的情况,则抄袭者与被抄袭者均 以0分计; 3. 课程结束后报告上交教师,并进行考核与存档。 三级项目报告格式规范 1. 正文:宋体,小四号,首行缩进2字符,1.5倍行距,段前段后 各0行; 2. 图表:居中,图名用五号字,中文用宋体,英文用“Times New Roman”,位于图表下方,须全文统一。

目录 一项目设计方案 (3) 二项目设计分析 (4) 三项目设计成果 (4) 四项目创新创业 (5) 五项目展望 (6) 附录一:项目成员 (6) 附录二:相关代码、电路图等 (6)

一项目设计方案 1、项目名称: 垃圾回收 2、项目要求及系统基本功能: 1)利用数据结构的知识独立完成一个应用系统设计 2)程序正常运行,能够实现基本的数据增加、删除、修改、查询等功能3)体现程序实现算法复杂度优化 4)体现程序的健壮性 二项目设计分析 1、系统预期实现基本功能: (结合本系统预期具体实现,描述出对应基本要求(增、删、改、查等)的具体功能) 1. 2. 3. 4. 5. 6. 7. 2、项目模块功能描述 (基本分为组织实施组织、程序功能模块编写、系统说明撰写等。其中程序功能子模块实现) 模块一: 主要任务:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 模块二: 主要任务:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 模块n: 主要任务:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

算法排序问题实验报告

《排序问题求解》实验报告 一、算法的基本思想 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

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

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

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

数据结构课程设计报告

《数据结构与算法》课程设计报告 学号: 班级序号: 姓名: 指导教师: 成绩: 中国地质大学信息工程学院地理信息系统系 2011年12 月

1.需求规格说明 【问题描述】 利用哈夫曼编码进行对已有文件进行重新编码可以大大提高减小文件大小,减少存储空间。但是,这要求在首先对一个现有文件进行编码行成新的文件,也就是压缩。在文件使用时,再对压缩文件进行解压缩,也就是译码,复原原有文件。试为完成此功能,写一个压缩/解压缩软件。 【基本要求】 一个完整的系统应具有以下功能: (1)压缩准备。读取指定被压缩文件,对文件进行分析,建立哈夫曼树,并给出分析结果(包括数据集大小,每个数据的权值,压缩前后文件的大小),在屏幕上输出。 (2)压缩。利用已建好的哈夫曼树,对文件进行编码,并将哈夫曼编码及文件编码后的数据一起写入文件中,形成压缩文件(*.Haf)。 (3)解压缩。打开已有压缩文件(*.Haf),读取其中的哈夫曼编码,构建哈夫曼树,读取其中的数据,进行译码后,写入文件,完成解压缩。 (4)程序使用命令行方式运行 压缩命令:SZip A Test.Haf 1.doc 解压缩命令:SZip X Test.Haf 2.doc或SZip X Test.Haf 用户输入的命令不正确时,给出提示。 (5)使用面向对象的思想编程,压缩/解压缩、哈夫曼构建功能分别构建类实现。 2.总体分析与设计 (1)设计思想: 1、压缩准备:1> 读文件,逐个读取字符,统计频率 2> 建立哈夫曼树 3> 获得哈弗曼编码 2、压缩过程: 1> 建立一个新文件,将储存权值和字符的对象数组取存储在文件头

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

? & 数据结构课程设计报告 —几种排序算法的演示( ; 时间: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)在二叉树的调试中,从广义表生成二叉树的模块花了较多时间调试。 由于一开始设计的广义表的字符串表示没有思考清晰,处理只有一个孩子的节点时发生了混乱。调试之初不以为是设计的问题,从而在代码上花了不少时间调试。 目前的设计是: Tree = Identifier(Node,Node) Node = Identifier | () | Tree Identifier = ASCII Character 例子:a(b((),f),c(d,e)) 这样便消除了歧义,保证只有一个孩子的节点和叶节点的处理中不存在问题。 (2)Huffman树的调试花了较长时间。Huffman编码本身并不难处理,麻烦的是输入输出。①Huffman编码后的文件是按位存储的,因此需要位运算。 ②文件结尾要刷新缓冲区,这里容易引发边界错误。 在实际编程时,首先编写了屏幕输入输出(用0、1表示二进制位)的版本,然后再加入二进制文件的读写模块。主要调试时间在后者。 二、要让演示版压缩程序具有实用性,哪些地方有待改进? (1)压缩文件的最后一字节问题。 压缩文件的最后一字节不一定对齐到字节边界,因此可能有几个多余的0,而这些多余的0可能恰好构成一个Huffman编码。解码程序无法获知这个编码是否属于源文件的一部分。因此有的文件解压后末尾可能出现一个多余的字节。 解决方案: ①在压缩文件头部写入源文件的总长度(字节数)。需要四个字节来存储这个信息(假定文件长度不超过4GB)。 ②增加第257个字符(在一个字节的0~255之外)用于EOF。对于较长的文件,

会造成较大的损耗。 ③在压缩文件头写入源文件的总长度%256的值,需要一个字节。由于最后一个字节存在或不存在会影响文件总长%256的值,因此可以根据这个值判断整个压缩文件的最后一字节末尾的0是否在源文件中存在。 (2)压缩程序的效率问题。 在编写压缩解压程序时 ①编写了屏幕输入输出的版本 ②将输入输出语句用位运算封装成一次一个字节的文件输入输出版本 ③为提高输入输出效率,减少系统调用次数,增加了8KB的输入输出缓存窗口 这样一来,每写一位二进制位,就要在内部进行两次函数调用。如果将这些代码合并起来,再针对位运算进行一些优化,显然不利于代码的可读性,但对程序的执行速度将有一定提高。 (3)程序界面更加人性化。 Huffman Tree Demo (C) 2011-12-16 boj Usage: huffman [-c file] [-u file] output_file -c Compress file. e.g. huffman -c test.txt test.huff -u Uncompress file. e.g. huffman -u test.huff test.txt 目前的程序提示如上所示。如果要求实用性,可以考虑加入其他人性化的功能。 三、调研常用的压缩算法,对这些算法进行比较分析 (一)无损压缩算法 ①RLE RLE又叫Run Length Encoding,是一个针对无损压缩的非常简单的算法。它用重复字节和重复的次数来简单描述来代替重复的字节。尽管简单并且对于通常的压缩非常低效,但它有的时候却非常有用(例如,JPEG就使用它)。 变体1:重复次数+字符 文本字符串:A A A B B B C C C C D D D D,编码后得到:3 A 3 B 4 C 4 D。

数据结构课程设计-排序

一、问题描述 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.课程设计任务内容 通过玩家与电脑双方的交替下棋,在一个8行8列的方格中,进行棋子的相互交替翻转。反复循环下棋,最后让双方的棋子填满整个方格。再根据循环遍历方格程序,判断玩家与电脑双方的棋子数。进行大小判断,最红给出胜负的一方。并根据y/n选项,判断是否要进行下一局的游戏。 2.课程设计要求 实现黑白两色棋子的对峙 开发环境:vc++6.0 实现目标: (1)熟悉的运用c语言程序编写代码。 (2)能够理清整个程序的运行过程并绘画流程图 (3)了解如何定义局部变量和整体变量; (4)学会上机调试程序,发现问题,并解决 (5)学习使用C++程序来了解游戏原理。 (6)学习用文档书写程序说明

摘要 本文的研究工作在于利用计算机模拟人脑进行下黑白棋,计算机下棋是人工智能领域中的一个研究热点,多年以来,随着计算机技术和人工智能技术的不断发展,计算机下棋的水平得到了长足的进步 该程序的最终胜负是由棋盘上岗双方的棋子的个数来判断的,多的一方为胜,少的一方为负。所以该程序主要运用的战术有削弱对手行动战术、四角优先战术、在游戏开局和中局时,程序采用削弱对手行动力战术,即尽量减少对手能够落子的位置;在游戏终局时则采用最大贪吃战术,即尽可能多的吃掉对手的棋子;而四角优先战术则是贯穿游戏的始终,棋盘的四角围稳定角,不会被对手吃掉,所以这里是兵家的必争之地,在阻止对手进角的同时,自己却又要努力的进角。 关键词:黑白棋;编程;设计

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

排序算法: (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)折半插入排序:

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

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

课程设计:排序综合 一、任务描述 利用随机函数产生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 ; //定义顺序表类型 四、功能设计 (一)主控菜单设计

数据结构课程设计报告

编号 课程设计 题目 1、一元稀疏多项式计算器 2、模拟浏览器操作程序 3、背包问题的求解 4、八皇后问题 二级学院计算机科学与工程学院 专业计算机科学与技术 班级 2011级 37-3班 学生姓名 XX 学号 XXXXXXXXXX 指导教师 XXXXX 评阅教师 时间 1、一元稀疏多项式计算器 【实验内容】 一元稀疏多项式计算器。

【问题描述】 设计一个一元稀疏多项式简单计算器。 【需求分析】 其基本功能包括: (1)输入并建立多项式; (2)输出多项式,输出形式为整数序列为:n,c1,e1,c2,e2,……,cn,en,其中n 是多项式的项数,ci,ei分别是第i项的系数和指数,序列按指数降序排序;(3)多项式a和b相减,建立多项a+b; (4)多项式a和b相减,建立多项式a-b; (5)计算多项式在x处的值; (6)计算器的仿真界面(选做); 【概要设计】 -=ADT=- { void input(Jd *ha,Jd *hb); void sort(dnode *h)

dnode *operate(dnode *a,dnode *b) float qiuzhi(int x,dnode *h) f",sum); printf("\n"); } 【运行结果及分析】 (1)输入多项式:

(2)输出多项式(多项式格式为:c1x^e1+c2x^e2+…+cnx^en): (3)实现多项式a和b相加: (4)实现多项式a和b相减: (5)计算多项式在x处的值:

2、模拟浏览器操作程序 【实验内容】 模拟浏览器操作程序 【问题描述】 标准Web浏览器具有在最近访问的网页间后退和前进的功能。实现这些功能的一个方法是:使用两个栈,追踪可以后退和前进而能够到达的网页。在本题中,要求模拟实现这一功能。 【需求分析】 需要支持以下指令: BACK:将当前页推到“前进栈”的顶部。取出“后退栈”中顶端的页面,使它成为当前页。若“后退栈”是空的,忽略该命令。 FORWARD:将当前页推到“后退栈”的顶部。取出“前进栈”中顶部的页面,使它成为当前页。如果“前进栈”是空的,忽略该命令。 VISIT:将当前页推到“后退栈”的顶部。使URL特指当前页。清空“前进栈”。 QUIT:退出浏览器。 假设浏览器首先加载的网页URL是:http:

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

数据结构课程设计报告 —几种排序算法的演示 时间: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、通过实际编译系统的分析设计、编程调试,掌握应用软件的分析方法和工程设计方法。4、通过课程设计,培养了我严肃认真的工作作风,逐步建立正确的生产观念、经济观念和全局观念。从刚开始得觉得很难,到最后把这个做出来,付出了很多,也得到了很多,以前总以为自己对编程的地方还不行,现在,才发现只要认真做,没有什么不可能。 编程时要认真仔细,出现错误要及时找出并改正,(其中对英语的要求也体现出来了,因为它说明错误的时候都是英语)遇到问题要去查相关的资料。反复的调试程序,最好是多找几个同学来对你的程序进行调试并听其对你的程序的建议,在他们不知道程序怎么写的时候完全以一个用户的身份来用对你的用户界面做一些建议,正所谓当局者迷旁观者清,把各个注意的问题要想到;同时要形成自己的编写程序与调试程序的风格,从每个细节出发,不放过每个知识点,注意与理论的联系和理论与实践的差别。另外,要注意符号的使用,注意对字符处理,特别是对指针的使用很容易出错且调试过程是不会报错的,那么我们要始终注意指针的初始化不管它怎么用以免不必要麻烦。 通过近两周的学习与实践,体验了一下离开课堂的学习,也可以理解为一次实践与理论的很好的连接。特别是本组所做的题目都是课堂上所讲的例子,在实行之的过程中并不是那么容易事让人有一种纸上谈兵的体会,正所谓纸上得来终觉浅绝知此事要躬行。实训过程中让我们对懂得的知识做了进一步深入了解,让我们的理解与记忆更深刻,对不懂的知识与不清楚的东西也做了一定的了解,也形成了一定的个人做事风格。 通过这次课程设计,让我对一个程序的数据结构有更全面更进一步的认识,根据不同的需求,采用不同的数据存储方式,不一定要用栈,二叉树等高级类型,有时用基本的一维数组,只要运用得当,也能达到相同的效果,甚至更佳,就如这次的课程设计,通过用for的多重循环,舍弃多余的循环,提高了程序的运行效率。在编写这个程序的过程中,我复习了之前学的基本语法,哈弗曼树最小路径的求取,哈弗曼编码及译码的应用范围,程序结构算法等一系列的问题它使我对数据结构改变了看法。在这次设计过程中,体现出自己单独设计模具的能力以及综合运用知识的能力,体会了学以致用、突出自己劳动成果的喜悦心情,也从中发现自己平时学习的不足和薄弱环节,从而加以弥补。 精品文档

数据结构课程设计报告

数据结构课程设计 设计说明书 TSP 问题 起止日期:2016 年 6 月27 日至2016 年7 月 1 日 学生姓名 班级 学号 成绩 指导教师( 签字) 2016 年7 月 1 日

目录 第1 章需求分析.................................................................................1... 1.1 简介 (1) 1.2 系统的开发背景 (1) 1.3 研究现状 (1) 第2 章概要设计.................................................................................2... 2.1 系统开发环境和技术介绍 (2) 2.2 系统需求分析 (2) 2.2.1 总体功能分析 (2) 2.2.2 核心功能分析 (3) 第3 章详细设计...................................................................................4... 3.1 系统开发流程 (4) 3.2 系统模块设计 (4) 3.3 系统结构 (6) 3.2 系统流程图 (6) 第4 章调试分析...................................................................................7... 4.1 程序逻辑调试 (7) 4.2 系统界面调试 (8) 第5 章测试结果...................................................................................9... 5.1 测试环境 (9) 5.2 输入输出测试项目 (9) 5.3 测试结果 (10) 结论.....................................................................................................1..1.. 参考文献................................................................................................1..1. 附录.......................................................................................................1..2..

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

数据结构课程设计报告 学院:计算机科学与工程 专业:计算机科学与技术 班级: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()函数,进入不同的功能函数中完成相关操作。

数据结构课程设计报告-学生成绩管理系统[]

武汉理工大学华夏学院课程设计报告书 课程名称:数据结构课程设计 题目:用C语言实现成绩统计程序的设计系名:信息工程系 专业班级:计算机1121 姓名:吴涛 学号:10210412104 指导教师:司晓梅 2016年3 月20日

武汉理工大学华夏学院信息工程系 课程设计任务书 课程名称:数据结构课程设计指导教师:司晓梅班级名称:计算机1121 开课系、教研室:信息系计算机 一、课程设计目的与任务 《数据结构》课程设计是为训练学生的数据组织能力和提高程序设计能力而设置的增强实践能力的课程。目的:学习数据结构课程,旨在使学生学会分析研究数据对象的特性,学会数据的组织方法,以便选择合适的数据的逻辑结构和存储结构以及相应操作,把现实世界中的问题转换为计算机内部的表示和处理,这就是一个良好的程序设计技能训练的过程。提高学生的程序设计能力、掌握基本知识、基本技能,提高算法设计质量与程序设计素质的培养就是本门课程的课程设计的目的。 任务:根据题目要求,完成算法设计与程序实现,并按规定写出课程设计报告。 二、课程设计的内容与基本要求 设计题目:用C语言实现成绩统计程序的设计 〔问题描述〕给出n个学生的m门课程的考试成绩信息,每条信息由姓名、课程代号与分数组成,要求设计算法: (1)输入每个人的各门课程的成绩,计算每人的平均成绩; (2)按平均成绩的高低次序,打印出个人的名次,平均成绩相同的为同一名次; (3)按名次列出每个学生的姓名和各科成绩; 〔基本要求〕学生的考试成绩必须通过键盘输入,且需对输出进行格式控制; 〔算法提示〕可以用选择排序、冒泡排序等多种排序算法求解; 具体要完成的任务是: A. 编制完成上述问题的C语言程序、进行程序调试并能得出正确的运行结果。 B. 写出规范的课程设计报告书; 三、课程设计步骤及时间进度和场地安排 时间:1周地点:现代教育中心 具体时间安排如下: 第一天:布置题目,确定任务、查找相关资料 第二天~第四天:功能分析,编写程序,调试程序、运行系统; 第五天上午:撰写设计报告; 第五天下午:程序验收、答辩。 四、课程设计考核及评分标准

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

实验课程:算法分析与设计 实验名称:几种排序算法的平均性能比较(验证型实验) 实验目标: (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

关于数据结构课程设计心得体会范文

关于数据结构课程设计心得体会范文 心得体会是指一种读书、实践后所写的感受性文字。是指将学习的东西运用到实践中去,通过实践反思学习内容并记录下来的文字,近似于经验总结。下面是小编搜集的关于数据结构课程设计心得体会范文,希望对你有所帮助。 关于数据结构课程设计心得体会(1) 这学期开始两周时间是我们自己选题上机的时间,这学期开始两周时间是我们自己选题上机的时间,虽然上机时间只有短短两个星期但从中确实学到了不少知识。上机时间只有短短两个星期但从中确实学到了不少知识。 数据结构可以说是计算机里一门基础课程,据结构可以说是计算机里一门基础课程,但我觉得我们一低计算机里一门基础课程定要把基础学扎实,定要把基础学扎实,然而这次短短的上机帮我又重新巩固了 c 语言知识,让我的水平又一部的提高。数据结构这是一门语言知识让我的水平又一部的提高。数据结构这是一门知识,纯属于设计的科目,它需用把理论变为上机调试。 纯属于设计的科目,它需用把理论变为上机调试。它对我们来说具有一定的难度。它是其它编程语言的一门基本学科。来说具有一定的难度。它是其它编程语言的一门基本学科。我选的上机题目是交叉合并两个链表,对这个题目,我选的上机题目是交叉合并两个链表,对这个题目,我觉得很基础。刚开始调试代码的时候有时就是一个很小的错觉得很基础。 刚开始调试代码的时候有时就是一个很小的错调试代码的时候误,导致整个程序不能运行,然而开始的我还没从暑假的状导致整个程序不能运行,态转到学习上,每当程序错误时我都非常焦躁,态转到学习上,每当程序错误时我都非常焦躁,甚至想到了放弃,但我最终找到了状态,一步一步慢慢来,放弃,但我最终找到了状态,一步一步慢慢来,经过无数次的检查程序错误的原因后慢慢懂得了耐心是一个人成功的必然具备的条件! 同时,通过此次课程设计使我了解到,必然具备的条件! 同时,通过此次课程设计使我了解到,硬件语言必不可缺少,要想成为一个有能力的人,必须懂得件语言必不可缺少,要想成为一个有能力的人,硬件

相关文档
最新文档