航空制造工程学院 20## 级学生专业课程设计任务书
100### 班 焊接工程 系 焊接技术与工程 专业
学 生: ###
日期:自 20##年 01月 04日至 20##年 01 月18日
指导教师: ### 系主任: ###
附注:任务书应该附在已完成的专业课程设计说明书首页。
航空制造工程学院 20## 级学生专业课程设计评语
姓名: 班级:
Ⅰ.专业课程设计题目:
Ⅱ.指导教师评语及评分
评语: 评分:
指导教师: 年 月 日
焊接工程 系主任:
第二篇:++专业课程设计任务书
计算机科学与技术 专业课程设计任务书
说明:本表由指导教师填写,由教研室主任审核后下达给选题学生,装订在设计(论文)首页
课 程 设 计
课程设计名称: 数据结构
专 业 班 级 :
学 生 姓 名 :
学 号 :
指 导 教 师 :课程设计时间:
一、需求分析
对任意给定的图(顶点数和边数自定义),建立它的邻接表输出,然后利用栈的五种基本运算(清空堆栈,压栈,弹出,取栈顶元素,判空栈)实现图的深度搜索遍历和广度优先搜素遍历算法
二、概要设计
邻接表是图的一种链式存储结构为,类似于树的孩子链表表法。在邻接表中,对图中每个顶点建立一个单链表,n个顶点,就要建n个链表。对于无向图,第i个单链表中的结点表示依赖于顶点vi的边。对于有向图是以顶点vi为尾的弧,
这个单链表称为顶点vi的单链表(即Vi的邻接表)。单链表中每一个结点称为表
结点,应包括两个域:邻接点域,用以存放与vi相邻接的顶点序号;链域用以指
向民vi邻接的下一个结点。另外,每一个单链表设一个表头结点。每一个表头
结点有两个域,一个用来存放顶点vi的信息;另一个域用来指向vi的邻接表中
的第一个结点。为了便于管理和随机访问任一顶点的单链表,将所有单链表的头结点组织成一个一维数组。
顶点
地址 顶点 链头 链针
邻接表的表头和表结点形式
typedef struct node{
int adjvex;//弧指向顶点的位置 struct node *next;//指向下一条弧的指针
}edgenode;//表结点
typedef struct {//头结点
char vertex;//顶点信息 edgenode *link;//指向第一条依附该顶点的弧的指针
}vexnode,AdjList[maxvertexnum];
建立邻接表的方法是:首先将邻接表表头数组初始化,第i个表头的vertex初始化为i,;link初始化为NULL。然后读入顶点对<i.j>,产生一个表结点,将j放入到该结点的adjvex域,将该结点链到邻接表的表头的T第i个表头的link域上。
深度优先遍历算法
1.现将所有的顶点标记为未访问
2.输出起始顶点,同时置起始顶点已访问的标记
3.将起始顶点进栈
4.当栈不为空时重复执行以下步骤
a取当前栈顶顶点
b若栈顶顶点存在未被访问的邻接结点,则选择一个顶点进行一下步骤: 输出该顶点
置该顶点已访问标记
将该顶点进栈
c否测当前顶点退栈
存储结构
typedef struct{//栈
int *data;//栈底指针 int *top;//栈顶指针
}seqstack;
广度优先遍历算法
1.现将所有的顶点标记为未访问
2.访问选定的起始顶点
3.置起始顶点已访问标记,并将该顶点入队
4.当队列不空时
a取对头顶点
b依次访问与顶点相邻的未被访问的顶点
访问该顶点
置该顶点为已被访问的标记,并将它入队 c当前对头元素顶点出队
d重复进行直到对空时结束
三、运行环境(软、硬件环境)
Windows98操作系统.VisualC++6.0软件环境下编译运行
四、开发工具和编程语言
开发工具和编程语言:(数据结构)C语言
数据结构(c语言)
五、详细设计
#include<stdio.h>
#include<stdlib.h>
#include <malloc.h>
#define False 0
#define True 1
#define Null 0
#define maxsize 20//队列的最大空间
#define maxvertexnum 20//最大顶点数
typedef struct node{
int adjvex;//弧指向顶点的位置 struct node *next;//指向下一条弧的指针 }edgenode;//表结点
typedef struct {//头结点
char vertex;//顶点信息 edgenode *link;//指向第一条依附该顶点的弧的指针
}vexnode,AdjList[maxvertexnum];
typedef struct{//图
AdjList adjlist;
int n,e;//n顶点数,e边数
}Graph;
typedef struct{//栈
int *data;//栈底指针 int *top;//栈顶指针
}seqstack;
//全局变量
vexnode g[maxvertexnum];//先定义后使用vexnode,邻接表g为全程变量 int visited[maxvertexnum]; //定义visit为全程向量
void CreatAdjList(Graph &G){
int i,j,k;//i,j为邻接点序号 edgenode *s; char c; printf("请输入定点数和边数:\n");
scanf("%d,%d",&G.n,&G.e);
c=getchar();
printf("请输入顶点信息(顶点号):\n"); for(i=1;i<=G.n;i++){//建立有n个顶点的顶点表 printf("第%d个顶点为",i);
scanf("%c",&G.adjlist[i].vertex);
c=getchar();
G.adjlist[i].link=NULL;
}
printf("请输入边的信息():\n"); for(k=1;k<=G.e;k++){//建立边表 printf("请输入请输入第%d条边起始顶点编号:\n",k); scanf("%d",&i);
printf("请输入请输入第%d条边终顶点编号:\n",k); scanf("%d",&j); s=(edgenode*)malloc(sizeof(edgenode));//分配顶点空间 s->adjvex=j;
s->next=G.adjlist[i].link;
G.adjlist[i].link=s;
}
}
void DisplayAdjList(Graph G)
{
int i;
edgenode *q;
for(i=1;i<=G.n;++i)
{
q=G.adjlist[i].link;
printf("%d",i);
while(q!=NULL)
{
printf("->%d",q->adjvex);
q=q->next;
}
printf("\n");
}
}
void DFSAL(Graph G)
{
edgenode *p;
seqstack s;
int i=1,t;
for(i=1;i<=G.n;i++) visited[i]=0; printf("这是深度优先遍历,遍历顺序为:\n");//输出起始顶点 s.data=(int*)malloc(maxsize*sizeof(seqstack));
s.top=s.data;//初始化栈 for(i=1;i<=G.n;i++)//考虑到图可能不连通 { p=G.adjlist[i].link; t=i; if(p==NULL)//p==NULL时,即该结点没有邻结点 { if(!visited[t]) { printf("%c",G.adjlist[t].vertex);//如果此时该结点没有被访问过,则访问
visited[t]=True; } continue;//即该结点没有邻结点,本次循环结束 } do{ if(p==NULL)//即到了图的最底层 { } s.top--;//没有下个邻接点,则退回前一个顶点 p=G.adjlist[*s.top].link; if(p!=NULL){ t=p->adjvex; } else if(!visited[t])//该结点中p!=NULL且其没有被访问过 { printf("%c",G.adjlist[t].vertex);//输出该顶点 visited[t]=True;//置为已访问
if(G.adjlist[t].link==NULL)continue; *s.top=t; s.top++;//进栈 p=G.adjlist[t].link;//p指针指到以G.adjlist[t].vertex为
起点的第一条边,如果//p==NULL
if(p==NULL)//如果该结点没有邻接点则输出之 { if(!visited[t])printf("%c",G.adjlist[t].vertex); } else t=p->adjvex;//如果该结点有邻接点,则把其邻接点的顶点号赋值给t
} else//如果该结点被访问过,且有邻结点,p指向以当前结点的邻接点为起点的边//也可能P=NULL
{ p=p->next;
if(p!=NULL)t=p->adjvex;//如果该邻接点有邻接点,则记下其
邻接点的位置
}
}while(s.top!=s.data);
}
}
void BFSAL(Graph G){
int v,Q[maxsize];
edgenode * w;
printf("这是广度优先遍历,遍历顺序为:\n"); int front=0,rear=0;//辅助队列置空 for(v=1;v<=G.n;v++)
visited[v]=0; for(v=1;v<=G.n;v++) if(!visited[v]) { visited[v]=1; printf("%c",G.adjlist[v].vertex); Q[rear]=v; rear++; //入队 while (front!=rear) { //队不空 front++; //出队 w=G.adjlist[v].link; while(w){ if(!visited[w->adjvex]) { visited[w->adjvex]=1;// 访问w;
printf("%c",G.adjlist[w->adjvex].vertex); Q[rear]=w->adjvex;
rear++;
}
w=w->next;
}
}
}
}
void main(){
Graph G;
int choice;
char ch;
printf("------创建邻接表存储的图");
CreatAdjList(G);
printf("已创建一个图了邻接表\n");
DisplayAdjList(G)
while(ch!='n'){
printf("\n请选择操作:");
printf("\n1------深度优先遍历:");
printf("\n2------广度优先遍历");
printf("\n3-----退出\n");
}
} scanf("%d",&choice); switch(choice){ case 1:DFSAL(G);break; case 2:BFSAL(G);break; case 3:ch='n';break; default:ch='n'; } }
六、调试分析
在图的创建过程中就遇到了问题,应为少了接受字符的getchar()函数,使得再输入顶点信息(字符型)后无法再执行CreatAdjlist()中剩下的语句,导致创建失败!再经同学提醒后成功创建了图。在图的深度和广度遍历时,由于其出的思路不够清晰,导致在写时漏考虑了一些情况致使无法得出想要的结果。在参阅了一些资料后,将思路搞清楚后,利用非递归得到了想要的结果!
七、测试结果
八、参考文献
在“课程设计报告”的最后应附上所参考的相关文献,
参考文献的书写格式如下:
书籍:作者,书名,版本,出版地,出版者,出版年,引用内容所在页码
论文:作者,论文篇名,刊物名,年月卷,论文在刊物中的页码
要求:必须独立完成,不能互相抄袭。设计完成后,将所完成的工作交由老师检查。并写出一份详细的实习报告。
数据结构课程设计总结
“要想学好一门语言,就要多用它!”虽然老师课上讲一些算法的思路很清楚,但是光靠课堂上的一些理论的知识远远不够的。那些只是一个基础,只有通过自己上机调试发现问题,解决问题才能更好,更深入的学好这门语言,运用好这门语言!就拿这次的课程设计来说,课程设计的目的是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程. 从拿到题目到完成整个编程,才短短一个星期。可是却学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且增强了自己的分析和调试能力。
这次我抽到的题目是图的遍历,这是之前的一道上机题,只是要求有点不同罢了。因此,开始准备实验比较晚,觉得即使实验中遇到困难了,到时问一下同学一会就能解决的。而且在写程序过程中一直把重点放在深度优先遍历和广度优先遍历那部分,觉得那才是整个课题的重点。可是令我没想到
的是,在用邻接表创建图的过程中就出现问题了,在CreatAdjList()函数中,在进入创建顶点信息的for循环之后,直接跳出了CreatAdjList()函数。本能的去查看循环条件可是当确定循环条件没错时,真的对它素手无册了。请教了几个同学,在那调试了半天也没结果。后来在机房一位经常调试程序的同学,一眼便看出了问题所在。是因为少了一个接受字符的getchar()函数。照他说的在一些地方增加了getchar()函数,调试了一下,真的能顺利创建了。小小高兴了一番!回去时忘保存修改稿,于是在自己的电脑上改,可是怎么都创建不成功。于是就在程序中瞎试,几乎把getchar()在哪都试了,最后搞了半天也不成。就在网上拼命找getchar()函数的用法,“getchar();的用法很多: 一种就是你这个程序用到的清空回车符 这种情况一般发生在在循环中涉及到输入的情况 ;还有一种是某些编译平台(IDE)在运行程序时并没有在程序运行后给人看结果的时间 这时候 在程序最后加上getchar()就能造成程序的暂停 给程序员度结果的机会”,在了解了大致的用法后,再改,可是还是不行。后来才发现是安装了近一年但却从未运行过的运行环境出问题了。可是通过这次的经历让我了解到了,其实如果要学好一门语言,平常的一些小的知识点自己也要多留意,不能忽视。因为一些看似不起眼的小知识点的残缺就有可能导致你的程序整个无法进行下去。还有可能由于平常很少上机调试的关系,在调试时遇到问题有时会有所局限,死盯着自己认为出问题的局部块查错。可是往往那样盯上几个小时都改不了那个错。
记得在网上曾看到过一篇谈论如何学习数据结构的文章:大意识这样的
1.如果没有学过C语言,或者C语言学的不好的时候把数据结构当成一本
数学书来学,它所讲述的都是一些简单的图论。在你的大脑中的主线不能丢失:线性结构,树结构和图结构。当你不再考虑复杂的程序设计时,仅仅研究个个离散点之间的关系,似乎数据结构也就不会那么难了。2.学习好了抽象的离散点关系后,再巩固一下你的C语言水平,书中描述的都是类C。因此你只要学习简单的C定义、判断、循环语句就基本能看的懂课本中所有程序了。 3.以上都完成后,从数据结构的线性表开始。线性表中顺序表似乎是为你学习C语言设计的,学好线性表的链表是你起步的关键。后面的树结构,图结构,排序,查找都少不了链式结构,往往这个也是最难的。
4.看程序的时候一定要自己在纸上画画,最好先学会画程序的流程图,也许那样你学程序也就会更快一些。
我想我在编程中最大的困难事是不知道如何去把自己的话转化成为程序。我想这可能和之前的c语言没有学好有很大的关系。
“数据结构”是一门专业的技术基础课。它需要我们学会分析计算机加工的数据结构的特性,初步了解算法的时间分析和空间分析,以便设计出简单实用的程序。此次的实验由于准备的较晚,因此都没有考虑我这个题该如何写才能使程序简单易读,而且能够在时间和空间上节省资源。不过相信以后在这方面会做得更好!