数据结构课程设计-图的遍历
- 格式:doc
- 大小:148.90 KB
- 文档页数:19
1图的遍历问题在实践中常常遇到这样的问题:给定n个点,从任一点出发对所有的点访问一次并且只访问一次。
如果用图中的顶点表示这些点,图中的边表示可能的连接,那么这个问题就可以表示成图的遍历问题,即从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。
图的遍历操作和树的遍历操作功能相似,是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础上。
由于图结构本身的复杂性,所以图的遍历操作也比较复杂,主要表现在以下几个方面:(1) 在图结构中,没有一个确定的首结点,图中任意一个顶点都可以作为第一个被访问的结点。
(2) 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上的所有顶点,因此,还需要考虑如何选取下一个出发点以访问图中其余的连通分量。
(3) 在图结构中,如果有回路存在,那么一个顶点被访问后,有可能沿回路又回到该顶点。
⑷在图结构中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,存在如何选取下一个要访问的顶点的问题。
基于以上分析,图的遍历方法目前有深度优先搜索(DFS)和广度优先搜索(BFS)两种算法。
下面将介绍两种算法的实现思路,分析算法效率并编程实现。
1.1深度优先搜索算法深度优先搜索算法是树的先根遍历的推广,它的实现思想是:从图G的某个顶点V o出发,访问V o,然后选择一个与V o相邻且没被访问过的顶点V i访问,再从V i出发选择一个与V i相邻且未被访问的顶点V j进行访问,依次继续。
如果当前被访问过的顶点的所有邻接顶点都已被访问,贝U退回已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样的方法向前遍历,直到图中所有顶点都被访问。
其递归算法如下:Boolean visited[MAX_VERTEX_NUM]; // 访问标志数组Status (*VisitFunc)(int v); //VisitFunc是访问函数,对图的每个顶点调用该函数void DFSTraverse (Graph G Status(*Visit)(i nt v)){VisitF unc = Visit;for(v=0; vvG.vex num; ++v)visited[v] = FALSE; //访问标志数组初始化for(v=0; v<G .vex num; ++v)if(!visited[v])DFS(G v); //对尚未访问的顶点调用DFS}void DFS(Graph G int v){ //从第v个顶点出发递归地深度优先遍历图Gvisited[v]=TRUE; VisitFunc(v); // 访问第v 个顶点for(w=FirstAdjVex(G ,v); w>=0;w=NextAdjVex(G ,v,w))//FirstAdjVex返回v的第一个邻接顶点,若顶点在G中没有邻接顶点,则返回空(0)。
数据结构课程教案一、课程概述本门课程旨在通过研究和探索数据结构的基础理论与实际应用,培养学生的问题分析与解决能力,提高其编程与算法设计水平。
通过本课程的研究,学生将会掌握各种基本数据结构的原理及其在实际问题中的应用,并能够独立设计和实现各种数据结构。
二、课程目标1. 理解数据结构的基本概念和原理;2. 掌握常见的数据结构,如数组、链表、栈、队列、树等;3. 熟练运用不同的数据结构解决实际问题;4. 提高编程能力,熟悉常见的数据结构算法设计与分析方法;5. 培养问题分析与解决的能力,加强团队合作和沟通能力。
三、教学内容1. 数据结构基础知识和基本概念;2. 线性结构:数组、链表、栈、队列;3. 树形结构:二叉树、平衡树、B树、堆、哈希表;4. 图:图的基本概念、图的遍历与搜索算法;5. 数据结构的算法设计与分析;6. 实际应用案例分析。
四、教学方法1. 理论讲授:通过课堂讲解,系统介绍数据结构的基本概念、原理和应用场景;2. 实践操作:通过实际案例和编程练,帮助学生掌握数据结构的实际应用和编程实现;3. 课堂互动:鼓励学生积极参与课堂讨论和问题解答,加强学生的问题分析和解决能力;4. 课程设计:组织学生进行课程设计项目,提高编程能力和团队协作能力。
五、教材与参考书籍1. 主教材:《数据结构(C语言版)》;2. 参考书籍:《算法导论》、《数据结构与算法分析》等。
六、评价与考核1. 平时成绩:包括课堂表现、作业质量和参与度;2. 期中考试:对学生对数据结构基本知识的掌握情况进行考核;3. 期末项目:要求学生独立完成一个数据结构的应用项目,并进行报告与展示。
七、教学进度安排1. 第1-2周:数据结构基础知识和概念介绍;2. 第3-5周:线性结构:数组、链表、栈、队列;3. 第6-8周:树形结构:二叉树、平衡树、B树、堆、哈希表;4. 第9-11周:图的基本概念和遍历算法;5. 第12-14周:算法设计与分析;6. 第15周:实际应用案例分析;7. 第16周:期末项目报告与展示。
数据结构与算法图的遍历与连通性数据结构与算法:图的遍历与连通性在计算机科学中,数据结构和算法是解决各种问题的基石。
其中,图作为一种重要的数据结构,其遍历和连通性的研究具有至关重要的意义。
让我们先来理解一下什么是图。
简单来说,图是由顶点(也称为节点)和边组成的结构。
顶点代表了事物或者对象,而边则表示顶点之间的关系。
例如,在一个社交网络中,人可以被视为顶点,而人与人之间的好友关系就是边。
图的遍历是指按照一定的规则访问图中的所有顶点。
常见的图遍历算法有深度优先遍历和广度优先遍历。
深度优先遍历就像是一个勇敢的探险家,一头扎进未知的领域,勇往直前,直到走投无路,然后回溯。
它的基本思想是先访问一个顶点,然后沿着一条未访问过的边递归地访问下一个顶点,直到没有可访问的边,再回溯到之前的顶点,继续探索其他未访问的边。
想象一下你在一个迷宫中,选择一条路一直走到底,直到遇到死胡同或者已经没有新的路可走,然后再返回之前的岔路口,选择另一条路继续前进。
广度优先遍历则像是一个谨慎的旅行者,逐层探索。
它先访问起始顶点,然后依次访问其所有相邻的顶点,再依次访问这些相邻顶点的相邻顶点,以此类推。
这就好比你在散播消息,先告诉离你最近的人,然后他们再告诉他们附近的人,一层一层地传播出去。
那么,为什么我们要进行图的遍历呢?这是因为通过遍历图,我们可以获取图的各种信息,比如顶点之间的关系、图的结构特点等。
在实际应用中,图的遍历有着广泛的用途。
例如,在搜索引擎中,通过遍历网页之间的链接关系来抓取和索引网页;在社交网络分析中,遍历用户之间的关系来发现社区结构等。
接下来,我们谈谈图的连通性。
连通性是指图中顶点之间是否存在路径相连。
如果从图中的任意一个顶点都可以到达其他任意一个顶点,那么这个图就是连通图;否则,就是非连通图。
判断图的连通性是一个重要的问题。
一种常见的方法是从某个顶点开始进行遍历,如果能够访问到所有的顶点,那么图就是连通的;否则,图是非连通的。
《数据结构课程设计》报告题目:深度与广度优先搜索--迷宫问题专业计算机科学与技术学生姓名李柏班级B计算机115学号1110704512指导教师巩永旺完成日期2013年1月11日目录1简介 (1)2算法说明 (1)3测试结果 (3)4分析与探讨 (7)5小结 (9)附录 (10)附录1 源程序清单 (10)迷宫问题1 简介1、图的存储结构图的存储结构又称图的表示,其最常用的方法是邻接矩阵和邻接表。
无论采用什么存储方式,其目标总是相同的,既不仅要存储图中各个顶点的信息,同时还要存储顶点之间的所有关系。
2、图的遍历图的遍历就是从指定的某个顶点(称其为初始点)出发,按照一定的搜索方法对图中的所有顶点各做一次访问过程。
根据搜索方法不同,遍历一般分为深度优先搜索遍历和广度优先搜索遍历。
本实验中用到的是广度优先搜索遍历。
即首先访问初始点v i,并将其标记为已访问过,接着访问v i的所有未被访问过的邻接点,顺序任意,并均标记为已访问过,以此类推,直到图中所有和初始点v i有路径相通的顶点都被访问过为止。
鉴于广度优先搜索是将所有路径同时按照顺序遍历,直到遍历出迷宫出口,生成的路径为最短路径。
因此我们采用了广度优先搜索。
无论是深度优先搜索还是广度优先搜索,其本质都是将图的二维顶点结构线性化的过程,并将当前顶点相邻的未被访问的顶点作为下一个顶点。
广度优先搜索采用队列作为数据结构。
本实验的目的是设计一个程序,实现手动或者自动生成一个n×m矩阵的迷宫,寻找一条从入口点到出口点的通路。
具体实验内容如下:选择手动或者自动生成一个n×m的迷宫,将迷宫的左上角作入口,右下角作出口,设“0”为通路,“1”为墙,即无法穿越。
假设一只老鼠从起点出发,目的为右下角终点,可向“上、下、左、右、左上、左下、右上、右下”8个方向行走。
如果迷宫可以走通,则用“■”代表“1”,用“□”代表“0”,用“☆”代表行走迷宫的路径。
输出迷宫原型图、迷宫路线图以及迷宫行走路径。
数据结构课程设计python一、课程目标知识目标:1. 理解数据结构的基本概念,掌握常用数据结构如列表、元组、字典和集合的特点及应用场景。
2. 学习并掌握栈和队列的操作原理及其在Python中的实现方法。
3. 掌握树和图的基本概念,了解二叉树、遍历算法及图的表示方法。
技能目标:1. 能够运用Python语言实现基本数据结构,并对其进行增、删、改、查等操作。
2. 能够利用栈和队列解决实际问题,如递归、函数调用栈、任务调度等。
3. 能够运用树和图解决实际问题,如查找算法、路径规划等。
情感态度价值观目标:1. 培养学生严谨的逻辑思维,提高分析问题和解决问题的能力。
2. 激发学生对数据结构和算法的兴趣,培养良好的编程习惯。
3. 引导学生认识到数据结构在实际应用中的重要性,增强学习热情和责任感。
课程性质:本课程为高年级数据结构课程,旨在使学生掌握Python语言实现数据结构的方法,提高编程能力和解决问题的能力。
学生特点:学生具备一定的Python编程基础,具有较强的逻辑思维能力,对数据结构有一定的了解。
教学要求:结合实际案例,采用任务驱动法,引导学生通过实践掌握数据结构的基本原理和应用方法。
注重培养学生的动手能力和团队协作精神,提高学生的综合素质。
通过本课程的学习,使学生能够具备独立设计和实现小型项目的能力。
二、教学内容1. 数据结构基本概念:介绍数据结构的概念、作用和分类,结合Python语言特点,分析各类数据结构在实际应用中的优势。
- 列表、元组、字典和集合的原理与应用- 栈与队列的操作原理及实现2. 线性表:讲解线性表的概念,重点掌握顺序表和链表的操作方法。
- 顺序表和链表的实现及操作- 线性表的查找和排序算法3. 树与二叉树:介绍树的基本概念,重点讲解二叉树的结构及其遍历算法。
- 树的基本概念和表示方法- 二叉树的性质、存储结构、遍历方法4. 图:讲解图的基本概念,掌握图的存储结构及遍历方法。
- 图的基本概念和表示方法- 图的遍历算法(深度优先搜索、广度优先搜索)- 最短路径和最小生成树算法5. 算法分析与设计:结合实例,分析算法性能,掌握基本的算法设计方法。
数据结构课设——有向图的深度、⼴度优先遍历及拓扑排序任务:给定⼀个有向图,实现图的深度优先, ⼴度优先遍历算法,拓扑有序序列,并输出相关结果。
功能要求:输⼊图的基本信息,并建⽴图存储结构(有相应提⽰),输出遍历序列,然后进⾏拓扑排序,并测试该图是否为有向⽆环图,并输出拓扑序列。
按照惯例,先上代码,注释超详细:#include<stdio.h>#include<stdlib.h>#include<malloc.h>#pragma warning(disable:4996)#define Max 20//定义数组元素最⼤个数(顶点最⼤个数)typedef struct node//边表结点{int adjvex;//该边所指向结点对应的下标struct node* next;//该边所指向下⼀个结点的指针}eNode;typedef struct headnode//顶点表结点{int in;//顶点⼊度char vertex;//顶点数据eNode* firstedge;//指向第⼀条边的指针,边表头指针}hNode;typedef struct//邻接表(图){hNode adjlist[Max];//以数组的形式存储int n, e;//顶点数,边数}linkG;//以邻接表的存储结构创建图linkG* creat(linkG* g){int i, k;eNode* s;//边表结点int n1, e1;char ch;g = (linkG*)malloc(sizeof(linkG));//申请结点空间printf("请输⼊顶点数和边数:");scanf("%d%d", &n1, &e1);g->n = n1;g->e = e1;printf("顶点数:%d 边数:%d\n", g->n, g->e);printf("请输⼊顶点信息(字母):");getchar();//因为接下来要输⼊字符串,所以getchar⽤于承接上⼀条命令的结束符for (i = 0; i < n1; i++){scanf("%c", &ch);g->adjlist[i].vertex = ch;//获得该顶点数据g->adjlist[i].firstedge = NULL;//第⼀条边设为空}printf("\n打印顶点下标及顶点数据:\n");for (i = 0; i < g->n; i++)//循环打印顶点下标及顶点数据{printf("顶点下标:%d 顶点数据:%c\n", i, g->adjlist[i].vertex);}getchar();int i1, j1;//相连接的两个顶点序号for (k = 0; k < e1; k++)//建⽴边表{printf("请输⼊对<i,j>(空格分隔):");scanf("%d%d", &i1, &j1);s = (eNode*)malloc(sizeof(eNode));//申请边结点空间s->adjvex = j1;//边所指向结点的位置,下标为j1s->next = g->adjlist[i1].firstedge;//将当前s的指针指向当前顶点上指向的结点g->adjlist[i1].firstedge = s;//将当前顶点的指针指向s}return g;//返回指针g}int visited[Max];//标记是否访问void DFS(linkG* g, int i)//深度优先遍历{eNode* p;printf("%c ", g->adjlist[i].vertex);visited[i] = 1;//将已访问过的顶点visited值改为1p = g->adjlist[i].firstedge;//p指向顶点i的第⼀条边while (p)//p不为NULL时(边存在){if (visited[p->adjvex] != 1)//如果没有被访问DFS(g, p->adjvex);//递归}p = p->next;//p指向下⼀个结点}}void DFSTravel(linkG* g)//遍历⾮连通图{int i;printf("深度优先遍历;\n");//printf("%d\n",g->n);for (i = 0; i < g->n; i++)//初始化为0{visited[i] = 0;}for (i = 0; i < g->n; i++)//对每个顶点做循环{if (!visited[i])//如果没有被访问{DFS(g, i);//调⽤DFS函数}}}void BFS(linkG* g, int i)//⼴度优先遍历{int j;eNode* p;int q[Max], front = 0, rear = 0;//建⽴顺序队列⽤来存储,并初始化printf("%c ", g->adjlist[i].vertex);visited[i] = 1;//将已经访问过的改成1rear = (rear + 1) % Max;//普通顺序队列的话,这⾥是rear++q[rear] = i;//当前顶点(下标)队尾进队while (front != rear)//队列⾮空{front = (front + 1) % Max;//循环队列,顶点出队j = q[front];p = g->adjlist[j].firstedge;//p指向出队顶点j的第⼀条边while (p != NULL){if (visited[p->adjvex] == 0)//如果未被访问{printf("%c ", g->adjlist[p->adjvex].vertex);visited[p->adjvex] = 1;//将该顶点标记数组值改为1rear = (rear + 1) % Max;//循环队列q[rear] = p->adjvex;//该顶点进队}p = p->next;//指向下⼀个结点}}}void BFSTravel(linkG* g)//遍历⾮连通图{int i;printf("⼴度优先遍历:\n");for (i = 0; i < g->n; i++)//初始化为0{visited[i] = 0;}for (i = 0; i < g->n; i++)//对每个顶点做循环{if (!visited[i])//如果没有被访问过{BFS(g, i);//调⽤BFS函数}}}//因为拓扑排序要求⼊度为0,所以需要先求出每个顶点的⼊度void inDegree(linkG* g)//求图顶点⼊度{eNode* p;int i;for (i = 0; i < g->n; i++)//循环将顶点⼊度初始化为0{g->adjlist[i].in = 0;}for (i = 0; i < g->n; i++)//循环每个顶点{p = g->adjlist[i].firstedge;//获取第i个链表第1个边结点指针while (p != NULL)///当p不为空(边存在){g->adjlist[p->adjvex].in++;//该边终点结点⼊度+1p = p->next;//p指向下⼀个边结点}printf("顶点%c的⼊度为:%d\n", g->adjlist[i].vertex, g->adjlist[i].in);}void topo_sort(linkG *g)//拓扑排序{eNode* p;int i, k, gettop;int top = 0;//⽤于栈指针的下标索引int count = 0;//⽤于统计输出顶点的个数int* stack=(int *)malloc(g->n*sizeof(int));//⽤于存储⼊度为0的顶点for (i=0;i<g->n;i++)//第⼀次搜索⼊度为0的顶点{if (g->adjlist[i].in==0){stack[++top] = i;//将⼊度为0的顶点进栈}}while (top!=0)//当栈不为空时{gettop = stack[top--];//出栈,并保存栈顶元素(下标)printf("%c ",g->adjlist[gettop].vertex);count++;//统计顶点//接下来是将邻接点的⼊度减⼀,并判断该点⼊度是否为0p = g->adjlist[gettop].firstedge;//p指向该顶点的第⼀条边的指针while (p)//当p不为空时{k = p->adjvex;//相连接的顶点(下标)g->adjlist[k].in--;//该顶点⼊度减⼀if (g->adjlist[k].in==0){stack[++top] = k;//如果⼊度为0,则进栈}p = p->next;//指向下⼀条边}}if (count<g->n)//如果输出的顶点数少于总顶点数,则表⽰有环{printf("\n有回路!\n");}free(stack);//释放空间}void menu()//菜单{system("cls");//清屏函数printf("************************************************\n");printf("* 1.建⽴图 *\n");printf("* 2.深度优先遍历 *\n");printf("* 3.⼴度优先遍历 *\n");printf("* 4.求出顶点⼊度 *\n");printf("* 5.拓扑排序 *\n");printf("* 6.退出 *\n");printf("************************************************\n");}int main(){linkG* g = NULL;int c;while (1){menu();printf("请选择:");scanf("%d", &c);switch (c){case1:g = creat(g); system("pause");break;case2:DFSTravel(g); system("pause");break;case3:BFSTravel(g); system("pause");break;case4:inDegree(g); system("pause");break;case5:topo_sort(g); system("pause");break;case6:exit(0);break;}}return0;}实验⽤图:运⾏结果:关于深度优先遍历 a.从图中某个顶点v 出发,访问v 。
《数据结构》课程设计题目《数据结构》课程设计题目课程设计题一:学生成绩管理系统设计目的:1.2.3. 掌握线性链表的建立。
掌握线性链表的基本操作。
掌握查找的基本算法。
设计内容:利用线性链表实现学生成绩管理系统,具体功能:输入、输出、插入、删除、查找、追加、读入、显示、保存、拷贝、排序、索引、分类合计、退出,并能在屏幕上输出操作前后的结果。
设计要求:1.2.3.写出系统需求分析,并建模。
编程实现,界面友好。
输出操作前后的结果。
课程设计题二:停车场管理系统设计目的:1.2.3.4. 掌握栈和队列的建立。
掌握栈和队列的基本操作。
深入了解栈和队列的特性,以便在解决实际问题中灵活运用它们。
加深对栈和队列的理解和认识。
设计内容:设有一个可以停放n辆汽车的狭长停车场,它只有一个大门可以供车辆进出。
车辆按到达停车场时间的早晚依次从停车场最里面向大门口处停放(最先到达的第一辆车放在停车场的最里面)。
如果停车场已放满n辆车,则后来的车辆只能在停车场大门外的便道上等待,一旦停车场内有车开走,则排在便道上的第一辆车就进入停车场。
停车场内如有某辆车要开走,在他之后进入停车场的车都必须先退出停车场为它让路,待其开出停车场后,这些车辆在依原来的次序进场。
每辆车在离开停车场时,都应依据它在停车场内停留的时间长短交费。
如果停留在便道上的车未进停车场就要离去,允许其离去,不收停车费,并且仍然保持在便道上等待的车辆的次序。
编制一程序模拟该停车场的管理。
设计要求:1. 以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。
2. 每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码以及到达或离去的时刻。
3. 对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车在停车场或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费,功能可自己添加)。
《数据结构》课程设计报告一、课程目标《数据结构》课程旨在帮助学生掌握计算机科学中数据结构的基本概念、原理及实现方法,培养其运用数据结构解决实际问题的能力。
本课程目标如下:1. 知识目标:(1)理解数据结构的基本概念,包括线性表、栈、队列、串、数组、树、图等;(2)掌握各类数据结构的存储表示和实现方法;(3)了解常见算法的时间复杂度和空间复杂度分析;(4)掌握排序和查找算法的基本原理和实现。
2. 技能目标:(1)能够运用所学数据结构解决实际问题,如实现字符串匹配、图的遍历等;(2)具备分析算法性能的能力,能够根据实际问题选择合适的算法和数据结构;(3)具备一定的编程能力,能够用编程语言实现各类数据结构和算法。
3. 情感态度价值观目标:(1)培养学生对计算机科学的兴趣,激发其探索精神;(2)培养学生团队合作意识,提高沟通与协作能力;(3)培养学生面对问题勇于挑战、善于分析、解决问题的能力;(4)引导学生认识到数据结构在计算机科学中的重要地位,激发其学习后续课程的兴趣。
本课程针对高年级学生,课程性质为专业核心课。
结合学生特点,课程目标注重理论与实践相结合,强调培养学生的实际操作能力和解决问题的能力。
在教学过程中,教师需关注学生的个体差异,因材施教,确保课程目标的达成。
通过本课程的学习,学生将具备扎实的数据结构基础,为后续相关课程学习和职业发展奠定基础。
二、教学内容根据课程目标,教学内容主要包括以下几部分:1. 数据结构基本概念:线性表、栈、队列、串、数组、树、图等;教学大纲:第1章 数据结构概述,第2章 线性表,第3章 栈和队列,第4章 串。
2. 数据结构的存储表示和实现方法:教学大纲:第5章 数组和广义表,第6章 树和二叉树,第7章 图。
3. 常见算法的时间复杂度和空间复杂度分析:教学大纲:第8章 算法分析基础。
4. 排序和查找算法:教学大纲:第9章 排序,第10章 查找。
教学内容安排和进度如下:1. 第1-4章,共计12课时,了解基本概念,学会使用线性表、栈、队列等解决简单问题;2. 第5-7章,共计18课时,学习数据结构的存储表示和实现方法,掌握树、图等复杂结构;3. 第8章,共计6课时,学习算法分析基础,能对常见算法进行时间复杂度和空间复杂度分析;4. 第9-10章,共计12课时,学习排序和查找算法,掌握各类算法的实现和应用。
数据结构课程设计报告班级:计算机科学与技术132班姓名:赖恒财指导教师:董跃华成绩:32信息工程学院2015 年7月8日目录图的最短路径算法实现1. 需求分析 (1)1.1 程序设计内容 (1)1.2 设计要求 (1)2.概要设计 (2)3.详细设计 (2)3.1 数据类型的定义 (2)3.2 功能模块的设计 (2)3.3 主程序流程 (9)4.调试分析 (10)4.1 问题回顾和分析 (10)4.2.经验和体会 (11)5.测试结果 (12)二叉树的遍历1.设计目的 (13)2.需求分析 (14)2.1课程设计的内容和要求 (14)2.2选题的意义及背景 (14)3.概要设计 (14)3.1设计思想 (14)3.2程序数据类型 (16)3.3程序模块分析 (16)3.3.1置空栈 (16)3.3.2入栈 (17)3.3.3出栈 (17)3.3.4取栈顶操作 (17)3.3.5判空栈 (17)3.4函数关系: (18)4.详细设计 (18)4.1二叉树算法程序截图和结果 (18)5.程序测试结果及问题分析 (19)6.总结 (20)参考文献 (21)附录1 (22)附录2 (26)图的最短路径算法实现----基于floyd最短路径算法1.需求分析设计校园平面图,所含景点不少于8个。
以图中顶点表示学校内各景点,存放景点的名称、景点介绍信息等;以边表示路径,存放路径长度信息。
要求将这些信息保存在文件graph.txt中,系统执行时所处理的数据要对此文件分别进行读写操作。
1.1程序设计内容1.从文件graph.txt中读取相应数据, 创建一个图,使用邻接矩阵表示图;2.景点信息查询:为来访客人提供校园任意景点相关信息的介绍;3.问路查询:为来访客人提供校园任意两个景点之间的一条最短路径。
1.2 设计要求(1) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。
(2) 程序要添加适当的注释,程序的书写要采用缩进格式。
沈航数据结构课程设计一、课程目标知识目标:1. 学生能理解数据结构的基本概念,掌握线性表、树、图等常见数据结构的特点与应用场景。
2. 学生能够掌握栈、队列、链表等线性数据结构的实现原理,并能够运用其解决实际问题。
3. 学生能够了解排序算法的原理,掌握冒泡排序、快速排序等常见排序算法,并能够分析其时间复杂度和空间复杂度。
技能目标:1. 学生能够运用所学数据结构设计并实现小型算法程序,解决实际问题。
2. 学生能够通过编程实践,掌握使用数据结构进行数据处理和分析的基本方法。
3. 学生能够运用调试工具,对数据结构相关程序进行调试和优化,提高程序性能。
情感态度价值观目标:1. 学生通过学习数据结构,培养逻辑思维能力和问题解决能力,增强对计算机科学的兴趣和热情。
2. 学生能够认识到数据结构在现实生活中的广泛应用,理解其在信息技术发展中的重要性。
3. 学生在学习过程中,培养合作精神、探究精神和创新意识,形成良好的编程习惯和学术道德。
课程性质:本课程为沈航计算机科学与技术专业核心课程,以理论教学与实践教学相结合,注重培养学生的动手能力和实际应用能力。
学生特点:学生具备一定的编程基础,对数据结构有一定了解,但可能对某些抽象概念和算法掌握不足。
教学要求:结合学生特点,采用案例教学、任务驱动等方法,引导学生主动探究,注重理论与实践相结合,提高学生的数据结构应用能力。
通过课程目标的分解,使学生在知识、技能和情感态度价值观方面得到全面提升。
后续教学设计和评估将以具体学习成果为依据,确保课程目标的实现。
二、教学内容1. 数据结构基本概念:包括数据结构定义、分类及其在计算机科学中的应用。
- 线性结构:线性表、栈、队列、数组、链表等。
- 非线性结构:树、图、散列表等。
2. 线性表及其实现:- 线性表的顺序存储和链式存储。
- 线性表的操作:插入、删除、查找等。
3. 栈和队列:- 栈的顺序存储和链式存储。
- 队列的顺序存储和链式存储。
摘要图(Graph)是一种复杂的非线性结构。
图可以分为无向图、有向图。
若将图的每条边都赋上一个权,则称这种带权图网络。
在人工智能、工程、数学、物理、化学、计算机科学等领域中,图结构有着广泛的应用。
在图结构中,对结点(图中常称为顶点)的前趋和后继个数都是不加以限制的,即结点之间的关系是任意的。
图中任意两个结点之间都可能相关。
图有两种常用的存储表示方法:邻接矩阵表示法和邻接表表示法。
在一个图中,邻接矩阵表示是唯一的,但邻接表表示不唯一。
在表示的过程中还可以实现图的遍历(深度优先遍历和广度优先遍历)及求图中顶点的度。
当然对于图的广度优先遍历还利用了队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)来实现。
这不仅让我们巩固了之前学的队列的基本操作,还懂得了将算法相互融合和运用。
目录第一章课程设计目的..................................................................................... 错误!未定义书签。
第二章课程设计内容和要求....................................................................... 错误!未定义书签。
2.1课程设计内容.................................................................................. 错误!未定义书签。
2.1.1图的邻接矩阵的建立与输出ﻩ错误!未定义书签。
2.1.2图的邻接表的建立与输出............................................... 错误!未定义书签。
2.1.3图的遍历的实现.................................................................... 错误!未定义书签。
数据结构课程设计题目以下7个题目任选其一。
1.排序算法比较利用随机函数产生30000个随机整数,利用插入排序、起泡排序、选择排序、快速排序、堆排序、归并排序等排序方法进行排序,并且(1)统计每一种排序上机所花费的时间。
(2)统计在完全正序,完全逆序情况下记录的比较次数和移动次数。
(3)比较的指标为关键字的比较次数和记录的移动次数(一次记录交换计为3次移动)。
(4)对结果作简单分析,包括对各组数据得出结果波动大小的解释。
2.图的深度遍历对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,然后利用堆栈的五种基本运算(清空堆栈、压栈、弹出、取栈顶元素、判栈空)实现图的深度优先搜索遍历。
画出搜索顺序示意图。
3.图的广度遍历对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,然后利用队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)实现图的广度优先搜索遍历。
画出搜索顺序示意图。
4.二叉树的遍历对任意给定的二叉树(顶点数自定)建立它的二叉链表存贮结构,并利用栈的五种基本运算(置空栈、进栈、出栈、取栈顶元素、判栈空)实现二叉树的先序、中序、后序三种遍历,输出三种遍历的结果。
画出搜索顺序示意图。
5.链表操作利用链表的插入运算建立线性链表,然后利用链表的查找、删除、计数、输出等运算反复实现链表的这些操作(插入、删除、查找、计数、输出单独写成函数的形式),并能在屏幕上输出操作前后的结果。
画出搜索顺序示意图。
6.一元稀疏多项式简单计数器(1)输入并建立多项式(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2……cn,en,其中n是多项式的项数,ci,ei分别为第i项的系数和指数。
序列按指数降序排列。
(3)多项式a和b相加,建立多项式a+b,输出相加的多项式。
(4)多项式a和b相减,建立多项式a-b,输出相减的多项式。
用带头结点的单链表存储多项式。
测试数据:(1)(2x+5x8-3.1x11)+(7-5x8+11x9)(2)(6x-3-x+4.4x2-1.2x9)-(-6x-3+5.4x2+7.8x15)(3)(x+x2+x3)+0(4)(x+x3)-(-x-x-3)7.实现两个链表的合并基本功能要求:(1)建立两个链表A和B,链表元素个数分别为m和n个。
关于数据的遍历方法数据遍历是指按照一定的规则和方法,遍历数据集合中的每个元素。
在计算机科学和信息技术领域,数据遍历是非常常见和重要的操作,可以用来查找特定数据、对数据进行处理和分析、进行数据可视化等。
数据遍历的方法有很多种,常用的方法包括线性遍历、递归遍历、并行遍历、深度优先遍历和广度优先遍历等。
下面将详细介绍这些遍历方法。
1.线性遍历:线性遍历是最常见和基本的数据遍历方法,也是最简单的方法。
线性遍历就是按顺序依次访问数据集合中的每个元素,无论是数组、链表还是其他数据结构。
线性遍历可以使用循环结构实现,比较常见的循环结构有for循环和while循环。
线性遍历的时间复杂度是O(n),其中n是数据集合的大小。
2.递归遍历:递归遍历是指通过递归的方式遍历数据集合。
递归是一种自我调用的方法,可以通过递归函数来实现对数据集合的遍历。
递归遍历的优点是代码简洁清晰,但是在大数据集合上可能存在性能问题。
递归遍历可以使用深度优先遍历或广度优先遍历的方式进行。
3.并行遍历:并行遍历是指同时遍历多个数据集合。
在多核处理器和分布式系统中,可以将不同的处理器或节点分配给不同的数据集合进行并行遍历。
并行遍历可以大大提高遍历大规模数据集合的效率,但同时也需要考虑数据同步和通信的问题。
4.深度优先遍历:深度优先遍历是一种先访问子节点再访问兄弟节点的遍历方式。
深度优先遍历一般使用递归或栈来实现。
在深度优先遍历中,先以深度优先的方式访问第一个子节点,然后再按深度优先的方式访问该子节点的子节点,直到最后一个子节点,然后回溯到上一级节点,继续访问该节点的兄弟节点,依此类推。
深度优先遍历通常用于查找特定数据或进行深度优先。
5.广度优先遍历:广度优先遍历是一种先访问兄弟节点再访问子节点的遍历方式。
广度优先遍历一般使用队列来实现。
在广度优先遍历中,首先访问根节点,然后按照广度优先的方式访问根节点的所有子节点,再逐层访问下去,直到访问到最后一层。
数据结构课程设计题目图的建立及输出学生姓名学号院系专业指导教师二O一O年12 月16 日目录一、设计题目 (2)二、运行环境(软、硬件环境) (2)三、算法设计的思想 (2)3.1邻接矩阵表示法 (2)3.2图的遍历 (4)3.3邻接矩阵的输出 (5)四、算法的流程图 (6)五、算法设计分析 (7)5.1无向网邻接矩阵的建立算法 (7)5.2无向图邻接矩阵的建立算法 (7)5.3图的深度优先遍历 (7)5.4图的广度优先遍历 (8)六、源代码 (8)七、运行结果分析 (14)八、收获及体会 (15)一、设计题目:图的建立及输出*问题描述:建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。
二、运行环境(软、硬件环境)*软件环境:Windows7、 Windows Vista、 Windows Xp等*硬件环境:处理器:Pentium4以上内存容量: 256M以上硬盘容量:40GB 以上三、算法设计的思想1、邻接矩阵表示法:设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。
G的邻接矩阵是一个他有下述性质的n阶方阵:1,若(Vi,Vj)∈E 或<Vi,Vj>∈E;A[i,j]={0,反之图5-2中有向图G1和无向图G2的邻接矩阵分别为M1和M2:M1=┌0 1 0 1 ┐│ 1 0 1 0 ││ 1 0 0 1 │└0 0 0 0 ┘M2=┌0 1 1 1 ┐│ 1 0 1 0 ││ 1 1 0 1 │└ 1 0 1 0 ┘注意无向图的邻接是一个对称矩阵,例如M2。
用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。
因此其类型定义如下:VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数和弧(边)数GraphKind kind; // 图的种类标志若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。
数据结构课程设计参考题目(一)数据结构是计算机科学中的一门基础课程,它主要研究数据的组织、存储、管理和操作等方面的问题。
随着计算机技术的发展,数据结构逐渐成为各个领域必不可少的一门课程。
而数据结构课程设计参考题目是该课程的一项重要内容,它能够帮助学生更好地掌握课程知识,提高对数据结构的理解和应用能力。
以下是几个数据结构课程设计参考题目。
1.链表操作设计一个链表类,使得它能够实现插入、删除、查找和遍历链表的操作。
要求采用单向链表或双向链表实现,并考虑链表的循环操作。
同时,要求能够对链表进行排序操作。
2.栈与队列操作设计一个栈和队列类,使得它们能够实现入栈、出栈、入队和出队的操作。
要求采用数组或链表实现,并可用于表达式转换和括号匹配等相关问题。
3.堆排序算法实现堆排序算法,要求能够对整型数列进行排序,并输出其排序后的结果。
要求堆的构建、删除和调整操作均可用最大堆或最小堆实现。
同时,要求能够对算法的时间复杂度进行分析,并与快速排序等算法进行比较。
4.哈希表实现设计一个哈希表类,使其能够实现插入、删除和查找等操作。
要求采用链地址法或开放地址法实现,同时需要考虑哈希函数和扩容等问题。
要求能够对哈希冲突的解决方法进行比较和分析。
5.树与图的遍历实现二叉树、B树或B+树的遍历操作,要求能够实现先序、中序和后序遍历,并能够循环遍历或递归遍历。
同时,要求能够对树的平衡性进行探究和讨论。
另外,树的遍历也是图的遍历的基础,可以通过深度优先搜索或广度优先搜索实现图的遍历。
以上是一些常见的数据结构课程设计参考题目,它们可以锻炼学生的编程能力、算法分析能力和数据处理能力,同时也可以增强学生对数据结构知识的理解和掌握。
数据结构课程设计题目,图的建立以及遍历。
2011-1-17 14:47提问者:doraprince|悬赏分:50 |浏览次数:1134次*问题描述:要求建立一个菜单,菜单包含4个菜单项供选择:1、建立图的邻接矩阵;2、建立图的邻接表;3、对图进行深度优先遍历;4、对图进行广度优先遍历。
要求从键盘输入无向有权图的顶点数、边数、每条边的起始顶点序号、终点序号、权值,将每条边的信息存入到邻接矩阵和邻接表中。
从键盘输入深度优先遍历和广度优先遍历图时初始出发的顶点的序号,要求在遍历过程中输出访问过的结点序号。
请用C语言编写,要求在TURBO C2.0下测试通过。
2011-1-23 13:33最佳答案//图的遍历算法程序//图的遍历是指按某条搜索路径访问图中每个结点,使得每个结点均被访问一次,而且仅被访问一次。
图的遍历有深度遍历算法和广度遍历算法,程序如下:#include <iostream>//#include <malloc.h>#define INFINITY 32767#define MAX_VEX 20 //最大顶点个数#define QUEUE_SIZE (MAX_VEX+1) //队列长度using namespace std;bool *visited; //访问标志数组//图的邻接矩阵存储结构typedef struct{char *vexs; //顶点向量int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵int vexnum,arcnum; //图的当前顶点数和弧数}Graph;//队列类class Queue{public:void InitQueue(){base=(int *)malloc(QUEUE_SIZE*sizeof(int));front=rear=0;}void EnQueue(int e){base[rear]=e;rear=(rear+1)%QUEUE_SIZE;}void DeQueue(int &e){e=base[front];front=(front+1)%QUEUE_SIZE;}public:int *base;int front;int rear;};//图G中查找元素c的位置int Locate(Graph G,char c){for(int i=0;i<G.vexnum;i++)if(G.vexs[i]==c) return i;return -1;}//创建无向网void CreateUDN(Graph &G){int i,j,w,s1,s2;char a,b,temp;printf("输入顶点数和弧数:");scanf("%d%d",&G.vexnum,&G.arcnum);temp=getchar(); //接收回车G.vexs=(char *)malloc(G.vexnum*sizeof(char)); //分配顶点数目printf("输入%d个顶点.\n",G.vexnum);for(i=0;i<G.vexnum;i++){ //初始化顶点printf("输入顶点%d:",i);scanf("%c",&G.vexs[i]);temp=getchar(); //接收回车}for(i=0;i<G.vexnum;i++) //初始化邻接矩阵for(j=0;j<G.vexnum;j++)G.arcs[i][j]=INFINITY;printf("输入%d条弧.\n",G.arcnum);for(i=0;i<G.arcnum;i++){ //初始化弧printf("输入弧%d:",i);scanf("%c %c %d",&a,&b,&w); //输入一条边依附的顶点和权值temp=getchar(); //接收回车s1=Locate(G,a);s2=Locate(G,b);G.arcs[s1][s2]=G.arcs[s2][s1]=w;}}//图G中顶点k的第一个邻接顶点int FirstVex(Graph G,int k){if(k>=0 && k<G.vexnum){ //k合理for(int i=0;i<G.vexnum;i++)if(G.arcs[k][i]!=INFINITY) return i;}return -1;}//图G中顶点i的第j个邻接顶点的下一个邻接顶点int NextVex(Graph G,int i,int j){if(i>=0 && i<G.vexnum && j>=0 && j<G.vexnum){ //i,j合理for(int k=j+1;k<G.vexnum;k++)if(G.arcs[i][k]!=INFINITY) return k;}return -1;}//深度优先遍历void DFS(Graph G,int k){int i;if(k==-1){ //第一次执行DFS时,k为-1for(i=0;i<G.vexnum;i++)if(!visited[i]) DFS(G,i); //对尚未访问的顶点调用DFS}else{visited[k]=true;printf("%c ",G.vexs[k]); //访问第k个顶点for(i=FirstVex(G,k);i>=0;i=NextVex(G,k,i))if(!visited[i]) DFS(G,i); //对k的尚未访问的邻接顶点i递归调用DFS }}//广度优先遍历void BFS(Graph G){int k;Queue Q; //辅助队列QQ.InitQueue();for(int i=0;i<G.vexnum;i++)if(!visited[i]){ //i尚未访问visited[i]=true;printf("%c ",G.vexs[i]);Q.EnQueue(i); //i入列while(Q.front!=Q.rear){Q.DeQueue(k); //队头元素出列并置为kfor(int w=FirstVex(G,k);w>=0;w=NextVex(G,k,w))if(!visited[w]){ //w为k的尚未访问的邻接顶点visited[w]=true;printf("%c ",G.vexs[w]);Q.EnQueue(w);}}}}//主函数void main(){int i;Graph G;CreateUDN(G);visited=(bool *)malloc(G.vexnum*sizeof(bool));printf("\n广度优先遍历: ");for(i=0;i<G.vexnum;i++)visited[i]=false;DFS(G,-1);printf("\n深度优先遍历: ");for(i=0;i<G.vexnum;i++)visited[i]=false;BFS(G);printf("\n程序结束.\n");}输出结果为(红色为键盘输入的数据,权值都置为1):输入顶点数和弧数:8 9输入8个顶点.输入顶点0:a输入顶点1:b输入顶点2:c输入顶点3:d输入顶点4:e输入顶点5:f输入顶点6:g输入顶点7:h输入9条弧.输入弧0:a b 1输入弧1:b d 1输入弧2:b e 1输入弧3:d h 1输入弧4:e h 1输入弧5:a c 1输入弧6:c f 1输入弧7:c g 1输入弧8:f g 1广度优先遍历: a b d h e c f g 深度优先遍历: a b c d e f g h 程序结束.只能劝之为1。
课程设计(论文)题目名称图的遍历课程名称数据结构课程设计学生姓名学号系、专业信息工程系、电子科学技术指导教师2012年12 月23 日目录1 前言 (2)2 需求分析 (2)2.1课程设计目的 (2)2.2课程设计任务 (2)2.3运行环境 (3)3 概要设计 (4)3.1总体设计流程 (4)3.2主函数流程图 (5)4 详细设计 (6)4.1实验的基本思想和基本原理 (6)4.2图的遍历 (6)5 算法描述 (9)5.1图的初始化 (9)5.2图的遍历 (10)6 结果与结论 (12)6.1源程序代码 (12)7课程设计总结 (17)参考文献 (18)致谢 (18)1 前言《数据结构》主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。
数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。
2 需求分析2.1课程设计目的学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。
通过课程设计可以提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。
通过此次课程设计主要达到以下目的:1.了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;2.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;3.提高综合运用所学的理论知识和方法独立分析和解决问题的能力;4.训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。
2.2课程设计任务1.问题分析和任务定义:根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么?(而不是怎么做?)限制条件是什么?2.逻辑设计:对问题描述中涉及的操作对象定义相应的数据类型,并按照以数据结构为中心的原则划分模块,定义主程序模块和各抽象数据类型。
逻辑设计的结果应写出每个抽象数据类型的定义(包括数据结构的描述和每个基本操作的功能说明),各个主要模块的算法;3.详细设计:定义相应的存储结构并写出各函数的伪码算法。
在这个过程中,要综合考虑系统功能,使得系统结构清晰、合理、简单和易于调试,抽象数据类型的实现尽可能做到数据封装,基本操作的规格说明尽可能明确具体。
详细设计的结果是对数据结构和基本操作作出进一步的求精,写出数据存储结构的类型定义,写出函数形式的算法框架并画出模块之间的调用关系图;4.程序编码:把详细设计的结果进一步求精为程序设计语言程序。
同时加入一些注解和断言,使程序中逻辑概念清楚;5.程序调试与测试:采用自底向上,分模块进行,即先调试低层函数。
能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。
调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果;2.3运行环境(1)WINDOWS 2000/2003/XP/7/Vista系统(2)Visual C++或TC集成开发环境3 概要设计3.1总体设计流程图图3.1 总体设计流程图3.2主函数流程图图3.2 主函数流程图4 详细设计4.1实验的基本思想和基本原理和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。
它是许多图的算法的基础。
遍历常用两种方法:深度优先搜索遍历;广度优先搜索遍历4.2图的遍历1.图的深度优先搜索深度优先搜索是一种递归的过程,正如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能“深”地搜索图。
在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边,就沿此边继续下去。
当结点v的所有边都己被探寻过,搜索将回溯到发现结点v有那条边的始结点。
这一过程一直进行到已发现从源结点可达的所有结点为止。
如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被发现为止。
<1>图的深度优先遍历的递归定义假设给定图4.1的初态是所有顶点均未曾访问过。
在图中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。
若w未曾访问过,则以w 为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。
若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。
图的深度优先遍历类似于树的前序遍历。
采用的搜索方法的特点是尽可能先对纵深方向进行搜索。
这种搜索方法称为深度优先搜索(Depth-First Search)。
相应地,用此方法遍历图就很自然地称之为图的深度优先遍历。
<2>深度优先搜索的过程设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。
若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。
上述过程直至从x出发的所有边都已检测过为止。
此时,若x不是源点,则回溯到在x 之前被访问过的顶点;否则图中所有和源点有路径相通的顶点(即从源点可达的所有顶点)都已被访问过,若图G是连通图,则遍历过程结束,否则继续选择一个尚未被访问的顶点作为新源点,进行新的搜索过程。
算法思路 :(1)、首先访问一个顶点vi(初始点),将其标记为已访问过(因为图的每个顶点可能有多个前驱和后继,所以当一个顶点被访问以后,必须记录它已经被访问,以避免再次被访问,为此设置一个辅助数组visited[n], 它的每个元素的初值均为逻辑值假(false),即为常量0,表明尚未被访问,一旦访问了顶点vi,就将对应元素visited[i]设置为逻辑值真,即为常量1,表明vi已被访问)。
(2)、然后从vi的任一未被访问过的邻接点出发进行深度优先搜索遍历,当vi 所有邻接点均被访问过,则退回到上一个顶点vk,从vk的另一个未被访问过的邻接点出发进行深度优先搜索遍历,直到退回到初始点并且没有未被访问过的邻接点为止。
图4.1(a)访问vo, 记录visited[0]=True, 从v0的一个未被访问过的邻接点v1出发遍历;(b)访问v1, visited[1]=True,从v1的一个未被访问过的邻接点v4出发遍历;(c)访问v4, visited[4]=True,从v4的一个未被访问过的邻接点v5出发遍历;(d)访问v5, visited[5]=True,由于v5的两个邻接点v1和v4都被访问过,退回上一邻接点v4,又v4的两个邻接点v1和v5都被访问过,再退回上一邻接点v1,从未被访问过邻接点V6出发遍历;(e)访问v6, visited[6]=True,从v6的一个未被访问过的邻接点v2出发遍历;(f)访问v2, visited[2]=True,v2所有邻接点都访问过,退回上一顶点v6,同理,v6退回v1,v1退回v0,再从v0未被访问过邻接点v3出发遍历;(g)访问v3, visited[3]=True,退回v0,因所有邻接点都访问过,再退回,结束。
2.图的广度优先搜索广度优先搜索算法(又称宽度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。
<1>广度优先搜索的基本思想首先访问图4.2中指定的起始点Vi并将其标记为已访问过,然后由Vi出发访问与它相邻接的所有顶点Vj、 Vk……,并均标记为已访问过,然后再按照Vj、Vk……的次序,访问每一个顶点的所有未被访问过的邻接顶点,并均标记为已访问过,下一步再从这些顶点出发访问与它们相邻接的尚未被访问的顶点,如此做下去,直到所有的顶点均被访问过为止在广度优先搜索中,若对顶点V1的访问先于顶点V2的访问,则对V1邻接顶点的访问也先于V2邻接顶点的访问。
就是说广度优先搜索中对邻接点的寻找具有“先进先出”的特性。
因此,为了保证访问顶点的这种先后关系,需借助一个队列暂存那些刚访问过的顶点。
设此队列由一个一维数组构成,数组名为Queue,队首指针和队尾指针分别为front和rear。
假设数组足够大,不必考虑有溢出的可能性。
广度优先搜索不是递归过程,不能用递归形式。
图4.2<2>遍历过程(1)访问v0,visited[0]=True(2)访问v0所有未访问过邻接v1和v2, visited[1]=True, visited[2]=True;(3)访问v1所有未被访问过的邻接点v3和v4,v5,并将它们标记已访问过;(4)访问v2所有未被访问过的邻接点v6, visited[6]=True;(5)访问v3所有未被访问过的邻接点v7, visited[7]=True;(6)访问v4所有未被访问过的邻接点(无)(7)访问v5所有未被访问过的邻接点v8, visited[8]=True;(8)访问v6所有未被访问过的邻接点(无);(9)依次访问v7,v8所有未被访问过的邻接点(无),结束。
5 算法描述5.1图的初始化1定义图typedef struct node{ /*边表结点*/int adjvex; /*邻接点域*/struct node *next; /*链域*/}EdgeNode;typedef struct vnode{ /*顶点表结点*/char vertex; /*顶点域*/EdgeNode *firstedge; /*边表头指针*/}VertexNode;typedef VertexNode AdjList[MaxVertexNum]; /*AdjList是邻接表类型*/ typedef struct {AdjList adjlist; /*邻接表*/int n,e; /*图中当前顶点数和边数*/} ALGraph; /*图类型*/2建立图的邻接表void CreatALGraph(ALGraph *G){int i,j,k;char a;EdgeNode *s; /*定义边表结点*/printf("Input VertexNum(n) and EdgesNum(e): ");scanf("%d,%d",&G->n,&G->e); /*读入顶点数和边数*/scanf("%c",&a);printf("Input Vertex string:");for(i=0;i<G->n;i++) /*建立边表*/{scanf("%c",&a);G->adjlist[i].vertex=a; /*读入顶点信息*/G->adjlist[i].firstedge=NULL; /*边表置为空表*/}printf("Input edges,Creat Adjacency List\n");for(k=0;k<G->e;k++) { /*建立边表*/scanf("%d%d",&i,&j); /*读入边(Vi,Vj)的顶点对序号*/s=(EdgeNode *)malloc(sizeof(EdgeNode)); /*/生成边表结点*/s->adjvex=j; /*邻接点序号为j*/s->next=G->adjlist[i].firstedge;G->adjlist[i].firstedge=s; /*将新结点*S插入顶点Vi的边表头部*/ s=(EdgeNode *)malloc(sizeof(EdgeNode));s->adjvex=i; /*邻接点序号为i*/s->next=G->adjlist[j].firstedge;G->adjlist[j].firstedge=s; /*将新结点*S插入顶点Vj的边表头部*/ }}5.2图的遍历1图的深度优先搜索<1>算法#define MAXVEX 100void dfs(adjlist g,int v,int n)/*从顶点v出发进行深度优先遍历*/{struct vexnode *stack[MAXVEX], *p;int visited[MAXVEX],top=0;for(i=1;i<=n;i++)visited[i]=0;printf(“%d”,v);p=g[v].link;visited[v]=1;while(top>0||p!=NULL){while(p!=NULL)if (visited[p->adjvex]==1)p=p->next;else{printf(“%d”,p->adjvex);visited[p->adjvex]=1;top++;stack[top]=p;p=g[p->adjvex].link;}if(top>0){top--;/*退栈,回溯查找已被访问结点的未被访问过的邻接点 */ p=stack[top];p =p->next;}}}<2>时间复杂性一个有n个顶点、e条边的图,在深度优先搜索图的过程中,找邻接点所需时间为O(e)。