课程设计论文图的遍历

合集下载

图的遍历算法

图的遍历算法

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:图的遍历功能:实现图的深度优先, 广度优先遍历算法,并输出原图结构及遍历结果。

分步实施:1) 初步完成总体设计,搭好框架;2)完成最低要求:两种必须都要实现,写出画图的思路;3)进一步要求:画出图的结构,有兴趣的同学可以进一步改进图的效果。

要求:1)界面友好,函数功能要划分好2)总体设计应画一流程图3)程序要加必要的注释4)要提供程序测试方案5)程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。

题目2:n维矩阵乘法:A B-1功能:设计一个矩阵相乘的程序,首先从键盘输入两个矩阵a,b的内容,并输出两个矩阵,输出ab-1结果。

分步实施:1)初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数;2)完成最低要求:建立一个文件,可完成2维矩阵的情况;3)一步要求:通过键盘输入维数n。

有兴趣的同学可以自己扩充系统功能。

要求:1)界面友好,函数功能要划分好2)总体设计应画一流程图3)程序要加必要的注释4)要提供程序测试方案5)程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。

题目3:数组应用功能:按照行优先顺序将输入的数据建成4维数组,再按照列优先顺序输出结果,给出任意处的元素值,并给出对应的一维数组中的序号。

分步实施:1.初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数;2.完成最低要求:完成第一个功能;3.进一步要求:进一步完成后续功能。

有兴趣的同学可以自己扩充系统功能。

要求:1)界面友好,函数功能要划分好2)总体设计应画一流程图3)程序要加必要的注释4)要提供程序测试方案5)程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。

题目4:数组应用2功能:读入数组下标,求出数组A靠边元素之和;求从A[0][0]开始的互不相邻的各元素之和;当m=n时,分别求两条对角线上的元素之和,否则打印出m!=n的信息。

数据结构实验报告图的遍历讲解

数据结构实验报告图的遍历讲解

数据结构实验报告图的遍历讲解一、引言在数据结构实验中,图的遍历是一个重要的主题。

图是由顶点集合和边集合组成的一种数据结构,常用于描述网络、社交关系等复杂关系。

图的遍历是指按照一定的规则,挨次访问图中的所有顶点,以及与之相关联的边的过程。

本文将详细讲解图的遍历算法及其应用。

二、图的遍历算法1. 深度优先搜索(DFS)深度优先搜索是一种常用的图遍历算法,其基本思想是从一个顶点出发,沿着一条路径向来向下访问,直到无法继续为止,然后回溯到前一个顶点,再选择此外一条路径继续访问。

具体步骤如下:(1)选择一个起始顶点v,将其标记为已访问。

(2)从v出发,选择一个未被访问的邻接顶点w,将w标记为已访问,并将w入栈。

(3)如果不存在未被访问的邻接顶点,则出栈一个顶点,继续访问其它未被访问的邻接顶点。

(4)重复步骤(2)和(3),直到栈为空。

2. 广度优先搜索(BFS)广度优先搜索是另一种常用的图遍历算法,其基本思想是从一个顶点出发,挨次访问其所有邻接顶点,然后再挨次访问邻接顶点的邻接顶点,以此类推,直到访问完所有顶点。

具体步骤如下:(1)选择一个起始顶点v,将其标记为已访问,并将v入队。

(2)从队首取出一个顶点w,访问w的所有未被访问的邻接顶点,并将这些顶点标记为已访问,并将它们入队。

(3)重复步骤(2),直到队列为空。

三、图的遍历应用图的遍历算法在实际应用中有广泛的应用,下面介绍两个典型的应用场景。

1. 连通分量连通分量是指图中的一个子图,其中的任意两个顶点都是连通的,即存在一条路径可以从一个顶点到达另一个顶点。

图的遍历算法可以用来求解连通分量的个数及其具体的顶点集合。

具体步骤如下:(1)对图中的每一个顶点进行遍历,如果该顶点未被访问,则从该顶点开始进行深度优先搜索或者广度优先搜索,将访问到的顶点标记为已访问。

(2)重复步骤(1),直到所有顶点都被访问。

2. 最短路径最短路径是指图中两个顶点之间的最短路径,可以用图的遍历算法来求解。

采用邻接表存储结构实现图的广度优先遍历。

采用邻接表存储结构实现图的广度优先遍历。

精心整理课程设计题目九:图的广度优先遍历基本要求:采用邻接表存储结构实现图的广度优先遍历。

(2)对任意给定的图(顶点数和边数自定),建立它的邻接表并输出;(3)实现图的广度优先遍历*/#include<iostream.h>#include<stdio.h>#include<malloc.h>#defineMAX_NUM20intvisited[MAX_NUM]={0};typedefintVertexType;typedefenum{DG=1,UDG}GraphKind;typedefstructArcNode{intadjvex;intweight;structArcNode*nextarc;ArcNode*info;}ArcNode;typedefstructVNode{VertexTypedata;ArcNode*firstarc;}VNode,AdjList[MAX_NUM];typedefstruct{AdjListvertices;intvexnum,arcnum;GraphKindkind;}ALGraph;voidPRIN(ALGraph&G);voidCreat_adjgraph(ALGraph&G);voidbfs(ALGraph&G,intv);voidCreat_adjgraphDG(ALGraph&G);voidCreat_adjgraphUDG(ALGraph&G);voidCreat_adjgraph(ALGraph&G);voidCreat_adjgraphDG(ALGraph&G){inti,s,d;ArcNode*p=NULL,*q=NULL;G.kind=DG;printf("请输入顶点数和边数:");scanf("%d%d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;++i){printf("第%d个顶点信息:",i+1);scanf("%d",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}for(i=0;i<G.arcnum;++i){printf("第%d条边的起始顶点编号和终止顶点编号:",i+1);scanf("%d%d",&s,&d);while(s<1||s>G.vexnum||d<1||d>G.vexnum){printf("编号超出范围,重新输入");scanf("%d%d",&s,&d);}s--;d--;p=new(ArcNode);p->adjvex=d;p->nextarc=G.vertices[s].firstarc;G.vertices[s].firstarc=p;}}voidCreat_adjgraphUDG(ALGraph&G){inti,s,d;ArcNode*p,*q;G.kind=UDG;printf("请输入顶点数和边数:");scanf("%d%d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;++i){printf("第%d个顶点信息:",i+1);scanf("%d",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}for(i=0;i<G.arcnum;++i){printf("第%d条边的起始顶点编号和终止顶点编号:",i+1);scanf("%d%d",&s,&d);while(s<1||s>G.vexnum||d<1||d>G.vexnum){printf("编号超出范围,重新输入");scanf("%d%d",&s,&d);}s--;d--;p=new(ArcNode);p->adjvex=d;p->nextarc=G.vertices[s].firstarc;G.vertices[s].firstarc=p;q=new(ArcNode);q->adjvex=s;q->nextarc=G.vertices[d].firstarc;G.vertices[d].firstarc=q;}}voidPRIN(ALGraph&G){inti;ArcNode*p;if(G.kind==DG||G.kind==UDG){for(i=0;i<G.vexnum;++i){printf("V%d:",G.vertices[i].data);p=G.vertices[i].firstarc;while(p!=NULL){printf("%d\t",p->adjvex+1);p=p->nextarc;}printf("\n");}}}voidbfs(ALGraph&G,intv){v--;ArcNode*p;intqueue[MAX_NUM],front=0,rear=0;intw,i;for(i=0;i<G.vexnum;i++)visited[i]=0;printf("%4d",v+1);visited[v]=1;rear=(rear+1)%MAX_NUM;queue[rear]=v;while(front!=rear){front=(front+1)%MAX_NUM;w=queue[front];p=G.vertices[w].firstarc;while(p!=NULL){if(visited[p->adjvex]==0){printf("%3d",p->adjvex+1);visited[p->adjvex]=1;rear=(rear+1)%MAX_NUM;queue[rear]=p->adjvex;}p=p->nextarc;}}printf("\n");}voidCreat_adjgraph(ALGraph&G){printf("1:有向图2:无向图\n");printf("请根据上述提示输入图的类型:");scanf("%d",&G.kind);switch(G.kind){caseDG:Creat_adjgraphDG(G);PRIN(G);break;caseUDG:Creat_adjgraphUDG(G);PRIN(G);break;default:printf("ERROR");break;}}voidmain(){ALGraphG;Creat_adjgraph(G);printf("\n");printf("广度优先搜索遍历序列为:\n");bfs(G,1);printf("\n");}。

图的遍历 实验报告

图的遍历  实验报告

图的遍历实验报告一、引言图是一种非线性的数据结构,由一组节点(顶点)和节点之间的连线(边)组成。

图的遍历是指按照某种规则依次访问图中的每个节点,以便获取或处理节点中的信息。

图的遍历在计算机科学领域中有着广泛的应用,例如在社交网络中寻找关系紧密的人员,或者在地图中搜索最短路径等。

本实验旨在通过实际操作,掌握图的遍历算法。

在本实验中,我们将实现两种常见的图的遍历算法:深度优先搜索(DFS)和广度优先搜索(BFS),并比较它们的差异和适用场景。

二、实验目的1. 理解和掌握图的遍历算法的原理与实现;2. 比较深度优先搜索和广度优先搜索的差异;3. 掌握图的遍历算法在实际问题中的应用。

三、实验步骤实验材料1. 计算机;2. 编程环境(例如Python、Java等);3. 支持图操作的相关库(如NetworkX)。

实验流程1. 初始化图数据结构,创建节点和边;2. 实现深度优先搜索算法;3. 实现广度优先搜索算法;4. 比较两种算法的时间复杂度和空间复杂度;5. 比较两种算法的遍历顺序和适用场景;6. 在一个具体问题中应用图的遍历算法。

四、实验结果1. 深度优先搜索(DFS)深度优先搜索是一种通过探索图的深度来遍历节点的算法。

具体实现时,我们可以使用递归或栈来实现深度优先搜索。

算法的基本思想是从起始节点开始,选择一个相邻节点进行探索,直到达到最深的节点为止,然后返回上一个节点,再继续探索其他未被访问的节点。

2. 广度优先搜索(BFS)广度优先搜索是一种逐层遍历节点的算法。

具体实现时,我们可以使用队列来实现广度优先搜索。

算法的基本思想是从起始节点开始,依次遍历当前节点的所有相邻节点,并将这些相邻节点加入队列中,然后再依次遍历队列中的节点,直到队列为空。

3. 时间复杂度和空间复杂度深度优先搜索和广度优先搜索的时间复杂度和空间复杂度如下表所示:算法时间复杂度空间复杂度深度优先搜索O(V+E) O(V)广度优先搜索O(V+E) O(V)其中,V表示节点的数量,E表示边的数量。

图的遍历的实验报告

图的遍历的实验报告

图的遍历的实验报告图的遍历的实验报告一、引言图是一种常见的数据结构,它由一组节点和连接这些节点的边组成。

图的遍历是指从图中的某个节点出发,按照一定的规则依次访问图中的所有节点。

图的遍历在许多实际问题中都有广泛的应用,例如社交网络分析、路线规划等。

本实验旨在通过实际操作,深入理解图的遍历算法的原理和应用。

二、实验目的1. 掌握图的遍历算法的基本原理;2. 实现图的深度优先搜索(DFS)和广度优先搜索(BFS)算法;3. 比较并分析DFS和BFS算法的时间复杂度和空间复杂度。

三、实验过程1. 实验环境本实验使用Python编程语言进行实验,使用了networkx库来构建和操作图。

2. 实验步骤(1)首先,我们使用networkx库创建一个包含10个节点的无向图,并添加边以建立节点之间的连接关系。

(2)接下来,我们实现深度优先搜索算法。

深度优先搜索从起始节点开始,依次访问与当前节点相邻的未访问过的节点,直到遍历完所有节点或无法继续访问为止。

(3)然后,我们实现广度优先搜索算法。

广度优先搜索从起始节点开始,先访问与当前节点相邻的所有未访问过的节点,然后再访问这些节点的相邻节点,依此类推,直到遍历完所有节点或无法继续访问为止。

(4)最后,我们比较并分析DFS和BFS算法的时间复杂度和空间复杂度。

四、实验结果经过实验,我们得到了如下结果:(1)DFS算法的时间复杂度为O(V+E),空间复杂度为O(V)。

(2)BFS算法的时间复杂度为O(V+E),空间复杂度为O(V)。

其中,V表示图中的节点数,E表示图中的边数。

五、实验分析通过对DFS和BFS算法的实验结果进行分析,我们可以得出以下结论:(1)DFS算法和BFS算法的时间复杂度都是线性的,与图中的节点数和边数呈正比关系。

(2)DFS算法和BFS算法的空间复杂度也都是线性的,与图中的节点数呈正比关系。

但是,DFS算法的空间复杂度比BFS算法小,因为DFS算法只需要保存当前路径上的节点,而BFS算法需要保存所有已访问过的节点。

遍历路径算法

遍历路径算法

遍历路径算法遍历路径算法是一种计算机科学中的算法,用于在图或树等数据结构中遍历或搜索路径,以找到特定节点、确定连通性或执行其他操作。

以下是一些常见的遍历路径算法:1. 深度优先搜索(Depth-First Search,DFS):DFS 是一种递归或堆栈(栈)驱动的算法,用于遍历树或图中的节点。

它首先探索一个节点的所有子节点,然后再递归地继续向下探索,直到到达叶子节点,然后返回上一级节点,继续探索其他子节点。

DFS 可以用于寻找路径、检测环、拓扑排序等问题。

2. 广度优先搜索(Breadth-First Search,BFS):BFS 以层次方式遍历图或树,从根节点开始,首先探索所有直接相邻的节点,然后再逐层向外扩展。

BFS 通常用于寻找最短路径或解决距离相关问题。

3. Dijkstra 算法:Dijkstra 算法用于寻找从一个起点到图中所有其他节点的最短路径。

它通过不断选择距离最短的节点来构建最短路径树。

4. A 搜索算法*:A* 搜索算法是一种启发式搜索算法,用于寻找从一个起点到目标节点的最短路径。

它使用启发式函数来评估节点的价值,并选择具有最小总代价的节点进行探索。

5. 贪婪搜索算法:贪婪搜索算法是一种启发式搜索算法,它总是选择最有希望的节点进行探索,但不一定能够找到全局最优解。

它通常用于解决某些优化问题,如旅行推销员问题。

6. 递归算法:递归算法是一种通过递归调用自身的方法,来遍历树或图中的路径。

递归算法可以用于深度优先搜索和其他遍历任务。

这些算法的选择取决于具体的问题和数据结构。

不同的遍历路径算法适用于不同类型的问题,因此需要根据问题的性质来选择适当的算法。

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

数据结构课设——有向图的深度、⼴度优先遍历及拓扑排序任务:给定⼀个有向图,实现图的深度优先, ⼴度优先遍历算法,拓扑有序序列,并输出相关结果。

功能要求:输⼊图的基本信息,并建⽴图存储结构(有相应提⽰),输出遍历序列,然后进⾏拓扑排序,并测试该图是否为有向⽆环图,并输出拓扑序列。

按照惯例,先上代码,注释超详细:#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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计论文图的遍历内蒙古科技大学本科生课程设计论文题目:C++课程设计-------图的遍历学生姓名:齐枫学号:1076807407专业:计算机10级班级:(4)班指导教师:2012年6月18日~2011年7月4日内蒙古科技大学课程设计任务书一、前言1.1课程设计的目的与意义 (4)1.2对课程设计功能的需求分析 (4)二、算法思想 (5)三、数据结构 (5)四、模块划分 (6)node* creategraph()//建立邻接表,完成无向图的输入void DepthFirstSearch(node *list)//深度优先搜索void BreadthFirstSearth(node *list)//广度优先搜索void PathSearth(node *list)//路径搜索void AdjacencyListDelete(node *list)//释放邻接表的空间AdjacencyListDelete(list);//释放邻接表空间五、系统的概要设计1、系统功能模块图 (9)六、源程序 (10)七、程序的调试分析以及测试结果1、程序的调试测试结果 (20)八、附录1、附录一心得 (21)2、参考文献 (22)一、前言1.1课程设计的目的与意义上学期我们对《数据结构》这门课程进行了学习。

这门课程是一门实践性非常强的课程,为了让大家更好地理解与运用所学知识,提高动手能力,我们进行了此次课程设计实习。

这次课程设计不但要求我们掌握《数据结构》中的各方面知识,还要求我们具备一定的C++语言基础和编程能力。

通过实践我们掌握《数据结构》中的知识。

对于《图的遍历》这一课题来说,所要求我们掌握的数据结构知识主要有:图的存储结构、队列的基本运算实现、图的深度优先遍历算法实现、图的广度优先遍历算法实现。

对于我们学生来讲,此次课程设计是为了让我们训练自己的实际设计能力,通过设计实践,去真正获得此项目管理和团队协作等方面的基本训练和工作经验。

通过课程设计的一系列训练,我们能提高如何综合运用所学知识解决实际问题的能力,以及获得此项目管理和团队协作等等众多方面的具体经验,增强对相关课程具体内容的理解和掌握能力,培养对整体课程知识综合运用和融会贯通能力。

1.2对课程设计功能的需求分析图的遍历并不需要是一个过于复杂的工作环境,一般来说:最合适的才是最好的。

软件设计必须符合我们使用实际情况的需要。

根据要求,图的遍历主要功能如下:1、用户可以随时建立一个有向图或无向图;2、用户可以根据自己的需要,对图进行深度遍历或广度遍历;3、用户可以根据自己的需要对图进行修改;4、在整个程序中,用户可以不断的按照不同的方式对图进行遍历,若不继续,用户也可以随时跳出程序,同时,如果用户输入的序号错误,程序会提示用户重新输入序号;二、算法思想本课题本人所采用的是邻接表的方式存储图,实现图的深度、广度两种遍历,并将每种遍历结果输出来。

并且能寻找路径。

2.1.1图的邻接矩阵的建立对任意给定的图(顶点数和边数自定),,根据邻接表的存储结构建立图的邻接表。

2.1.2 图的遍历的实现邻接表是图的一种链式存储结构,在邻接表中,对图中的每一个顶点建立一个单链表,通常以顺序结构存储,以便随机访问任意一顶点。

图的深度遍历,假设初始状态是图中所有顶点都未曾被访问,则深度优先遍历可从图中的某个顶点v出发,访问此顶点,依次从v的未被访问的邻接点出发深度优先遍历图,直至图中和v有路径想通的顶点都被访问到;若此时图中尚有未被访问的节点,则另选图中一个未被访问的顶点做起始点,直至所有节点都被访问。

图的广度优先遍历,是以v为起始点,由近及远,依次访问和v有路径相通且路径长度为1、2、…的顶点。

三、数据结构#define t true#define f false#include<iostream.h>struct node//定义一个结构作为节点类型{int data;bool sign;//标志位,用来标示是否遍历过node *next;};四、模块划分node* creategraph()//建立邻接表,完成无向图的输入};表4.1邻接表的建立void DepthFirstSearch(node *list)//深度优先搜索void DepthFirstSearch(node *list)cin>>k;a[i]=k图4.2 深度优先遍历流程图void BreadthFirstSearth(node *list)//广度优先搜索表4.3图的广度遍历void PathSearth(node *list)//路径搜索void AdjacencyListDelete(node *list)//释放邻接表的空间AdjacencyListDelete(list);//释放邻接表空间五、系统的概要设计main() /*包含一些调用和控制语句*/图5.1系统功能模块图六、部分源程序#define t true#define f false#include<iostream.h>struct node//定义一个结构作为节点类型{int data;bool sign;//标志位,用来标示是否遍历过node *next;};node* creategraph()//建立邻接表,完成无向图的输入{int l,m,n;bool g;cout<<"请输入节点数: ";cin>>n;node *adjacencylist=new node[n+1];//动态分配节点数组内存adjacencylist[0].data=n;//0地址存放的为节点数adjacencylist[0].next=NULL;for(int i=1;i<=n;i++)//给各顶点域赋初值{adjacencylist[i].data=0;adjacencylist[i].next=NULL;adjacencylist[i].sign=f;//表示未遍历}cout<<"请依次输入各条边的始点和尾点:(以0表示结束)"<<endl; cin>>l;if(l!=0)//判断输入边是否结束g=t;while(g==t){cin>>m;if((l>0)&&(l<=n)&&(m>0)&&(m<=n))//判断输入顶点是否正确{node *p,*q,*top;p=(node *)new(node);//分配边的一个顶点内存p->data=m;p->next=NULL;if(adjacencylist[l].next==NULL)//为每个节点创建邻接链表adjacencylist[l].next=p;else{top=adjacencylist[l].next;while(top->next!=NULL)top=top->next;top->next=p;}adjacencylist[l].data++;//统计邻接点的个数q=(node *)new(node);//分配边的另一个顶点内存q->data=l;q->next=NULL;if(adjacencylist[m].next==NULL)//构建邻接表adjacencylist[m].next=q;else{top=adjacencylist[m].next;while(top->next!=NULL)top=top->next;top->next=q;}adjacencylist[m].data++;//统计邻接点的个数}elsecout<<"边"<<l<<"--"<<m<<"输入错误!"<<endl;//错误输入标识cin>>l;if(l==0)//边的输入结束g=f;}return adjacencylist;//返回邻接表};void DepthFirstSearch(node *list)//深度优先搜索{int m,n=list[0].data,k,*a=new int[n];//设置一个数组用于存放节点node *p;cout<<"采用深度优先搜索:"<<endl;cout<<"请输入搜索起始节点:";cin>>k;for(int i=0;i<n;i++){a[i]=k;list[k].sign=t;if(i==n-1)break;m=0;while(list[k].sign==t){p=list[k].next;while(p!=NULL)//找出list[k]链表中的未遍历节点{k=p->data;p=p->next;if(list[k].sign==f)break;}m++;if(list[k].sign!=f)//判断是否是p=NULL跳出while循环的{if(i<m)//无节点可回溯{cout<<"该图为非连通图!"<<endl;break;}elsek=a[i-m]; //回溯}}for(i=1;i<=n;i++)//恢复原邻接表list[i].sign=f;cout<<"深度优先搜索遍历顺序为:";for(i=0;i<n;i++)//输出遍历结果cout<<a[i]<<" ";cout<<endl;delete a;//释放动态数组内存};void BreadthFirstSearth(node *list)//广度优先搜索{int m,r,k,n=list[0].data,*a=new int[n+1];//设置数组存放节点node *p;cout<<"采用广度优先搜索:"<<endl;cout<<"请输入搜索起始节点:";cin>>k;a[0]=n;a[1]=k;list[k].sign=t;//标识遍历的第一个节点m=0;r=1;while(m!=r){m++;p=list[a[m]].next;while(p!=NULL){k=p->data;if(list[k].sign==f)r++;a[r]=k;//遍历到的节点存入数组list[k].sign=t;//标识已经遍历过的节点}p=p->next;}}for(int i=1;i<=n;i++)//恢复原邻接表list[i].sign=f;cout<<"广度优先搜索遍历顺序为: ";for(i=1;i<=n;i++)//输出遍历cout<<a[i]<<" ";cout<<endl;delete a;//释放动态数组内存};void PathSearth(node *list)//路径搜索{int *a,c,d,m,k,n=list[0].data;cout<<"请输入起始点:";cin>>k;cout<<"请输入尾节点:";cin>>c;cout<<"请输入要找的路径长度:";cin>>d;d=d+1;if(d>n)cout<<"不存在这样的简单路径!"<<endl;else{a=new int[d];//动态分配数组内存存放路径上的节点for(int i=0;i<d;i++)a[i]=0;a[0]=k;node *p;int x;list[a[0]].sign=t;i=1;while(a[d-1]!=c){while(i<d){x=1;p=list[a[i-1]].next;while(p!=NULL){m=p->data;if(i==d-1&&m==a[0]&&a[0]==c)//路径存在且为回路{cout<<"该路径为一条回路!"<<endl;a[i]=m;i++;break;}if(list[m].sign==f){if(a[i]!=0){if(x==0)//是否为已经判断过的错误路径{a[i]=m;list[a[i]].sign=t;//标识走过节点i++;break;}if(a[i]==m)//设置错误路径标识x=0;}else{a[i]=m;list[a[i]].sign=t;//标识走过节点i++;break;}}p=p->next;}if(p==NULL){a[i]=0;i--;//由此节点往下的路径不存在,回溯list[a[i]].sign=f; //还原标识符}if(i==0)//无法回溯,路径不存在,跳出循环{cout<<"不存在这样的简单路径!"<<endl;break;}}if(i==0)//无法回溯,路径不存在,跳出循环break;if(a[d-1]!=c)//路径不是所要找的{i--; //回溯if(i>=0)list[a[i]].sign=f;//还原标识符}}if(a[d-1]==c)//判断路径是否找到并输出{cout<<"从节点"<<k<<"到节点"<<c<<"的一条路径为:";for(i=0;i<d-1;i++)//输出路径cout<<a[i]<<"--> ";cout<<a[d-1]<<endl;}delete a;}for(int i=1;i<=n;i++)//恢复原邻接表list[i].sign=f;};void AdjacencyListDelete(node *list)//释放邻接表的空间{node *p,*q;int n=list[0].data;for(int i=1;i<=n;i++){p=list[i].next;while(p!=NULL){q=p->next;delete p;//释放链表节点空间p=q;}}delete list;//释放邻接表空间};void main(){node *list;list=creategraph();//以邻接表的形式建立一个无向图char a,b;cout<<"请选择遍历方法:(d:深度优先搜索;b:广度优先搜索)";for(int i=1;i<2;i++){cin>>a;switch(a){case 'd':case 'D': DepthFirstSearch(list);cout<<"是否采用广度优先搜索重新遍历?(y:是;n:否)";cin>>b;if((b=='y')||(b=='Y'))BreadthFirstSearth(list);break;case 'b':case 'B': BreadthFirstSearth(list);cout<<"是否采用深度优先搜索重新遍历?(y:是;n:否)";cin>>b;if((b=='y')||(b=='Y'))DepthFirstSearch(list);break;default: cout<<"输入错误!请重新输入!"<<endl;i--;}}while(1){cout<<"是否搜索路径?(y:是;n:否)";cin>>a;if((a=='y')||(a=='Y'))PathSearth(list);else if((a=='n')||(a=='N'))break;elsecout<<"输入错误!"<<endl;}AdjacencyListDelete(list);//释放邻接表空间}七、程序的调试分析以及测试结果7.1程序的调试分析程序的调试是一个很重要的方面,本题目有个创建邻接表函数这是个基础,如果这里出了差错当然后面的模块也就无法进行了。

相关文档
最新文档