图的深度广度优先遍历操作代码
图的深度和广度
图的深度优先遍历和广度优先遍历Java实现收藏
一图的基本概念及存储结构
图G是由顶点的有穷集合,以及顶点之间的关系组成,顶点的集合记为V,顶点之间的关系构成边的集合E
G=(V,E).
说一条边从v1,连接到v2,那么有v1Ev2(E是V上的一个关系)《=》↔E.
图有有向图,无向图之分,无向图的一条边相当于有向图的中两条边,即如果无向图的顶点v1和v2之间有一条边
,那么既有从v1连接到v2的边,也有从v2连接到v1的边,↔E 并且↔E,而有向图是严格区分方向的。
一般图的存储有两种方式
1)相邻矩阵,用一个矩阵来保持边的情况,↔E则Matrix[v1][v2]=Weight.
2)邻接表,需要保存一个顺序存储的顶点表和每个顶点上的边的链接表。
这里的实现采用第二种方案,另外图又复杂图,简单图之分,复杂图可能在两点之间同一个方向有多条边,我们考虑的都是无环简单图,无环简单图是指顶点没有自己指向自己的边的简单图,即任取vi属于V => 不属于E并且没有重复边。
我们先给出图的ADT:
package algorithms.graph;
/**
* The Graph ADT
* @author yovn
*
*/
public interface Graph {
//mark
public static interface Edge{
public int getWeight();
}
int vertexesNum();
int edgeNum();
boolean isEdge(Edge edge);
void setEdge(int from,int to, int weight);
深度优先遍历算法实现及复杂度分析
深度优先遍历算法实现及复杂度分析深度优先遍历算法(Depth First Search, DFS)是一种常用的图遍历
算法,用于查找或遍历图的节点。本文将介绍深度优先遍历算法的实
现方法,并进行对应的复杂度分析。
一、算法实现
深度优先遍历算法的基本思想是从图的某个节点出发,沿着深度方
向依次访问其相邻节点,直到无法继续下去,然后返回上一层节点继
续遍历。下面是深度优先遍历算法的伪代码:
```
1. 初始化访问标记数组visited[],将所有节点的访问标记置为false。
2. 从某个节点v开始遍历:
- 标记节点v为已访问(visited[v] = true)。
- 访问节点v的相邻节点:
- 若相邻节点w未被访问,则递归调用深度优先遍历算法
(DFS(w))。
3. 遍历结束,所有节点都已访问。
```
二、复杂度分析
1. 时间复杂度
深度优先遍历算法的时间复杂度取决于图的存储方式和规模。假设图的节点数为V,边数为E。
- 邻接表存储方式:对于每个节点,需要访问其相邻节点。因此,算法的时间复杂度为O(V+E)。
- 邻接矩阵存储方式:需要检查每个节点与其他节点的连通关系,即需要遍历整个邻接矩阵。因此,算法的时间复杂度为O(V^2)。
2. 空间复杂度
深度优先遍历算法使用了一个辅助的访问标记数组visited[]来记录每个节点的访问状态。假设图的节点数为V。
- 邻接表存储方式:访问标记数组visited[]的空间复杂度为O(V)。
- 邻接矩阵存储方式:访问标记数组visited[]的空间复杂度同样为O(V)。
综上所述,深度优先遍历算法的时间复杂度为O(V+E),空间复杂度为O(V)。
dfs和bfs算法代码
dfs和bfs算法代码
深度优先搜索(DFS)和广度优先搜索(BFS)是常用的图遍历算法,它们可以帮助我们解决很多实际问题。本文将详细介绍这两种算法的实现原理和应用场景。
一、深度优先搜索(DFS)
深度优先搜索是一种递归的搜索算法,它从图的某个顶点开始,沿着一条路径尽可能深地搜索,直到无法继续为止,然后回溯到上一级节点,继续搜索其他路径。DFS一般使用栈来实现。
DFS的代码实现如下:
```
def dfs(graph, start):
visited = set() # 用一个集合来记录已访问的节点
stack = [start] # 使用栈来实现DFS
while stack:
node = stack.pop() # 取出栈顶元素
if node not in visited:
visited.add(node) # 将节点标记为已访问
neighbors = graph[node] # 获取当前节点的邻居节点
stack.extend(neighbors) # 将邻居节点入栈
return visited
```
DFS的应用场景很多,比如迷宫问题、拓扑排序、连通分量的计算等。在迷宫问题中,我们可以使用DFS来寻找从起点到终点的路径;在拓扑排序中,DFS可以用来确定任务的执行顺序;在连通分量的计算中,DFS可以用来判断图是否连通,并将图分割成不同的连通分量。
二、广度优先搜索(BFS)
广度优先搜索是一种逐层遍历的搜索算法,它从图的某个顶点开始,先访问该顶点的所有邻居节点,然后再访问邻居节点的邻居节点,依次进行,直到遍历完所有节点。BFS一般使用队列来实现。
数据结构课设——有向图的深度、广度优先遍历及拓扑排序
数据结构课设——有向图的深度、⼴度优先遍历及拓扑排序
任务:给定⼀个有向图,实现图的深度优先, ⼴度优先遍历算法,拓扑有序序列,并输出相关结果。
功能要求:输⼊图的基本信息,并建⽴图存储结构(有相应提⽰),输出遍历序列,然后进⾏拓扑排序,并测试该图是否为有向⽆环图,并输出拓扑序列。
按照惯例,先上代码,注释超详细:
#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));//申请结点空间
深度优先搜索算法详解及代码实现
深度优先搜索算法详解及代码实现深度优先搜索(Depth-First Search,DFS)是一种常见的图遍历算法,用于遍历或搜索图或树的所有节点。它的核心思想是从起始节点开始,沿着一条路径尽可能深入地访问其他节点,直到无法继续深入为止,然后回退到上一个节点,继续搜索未访问过的节点,直到所有节点都被访问为止。
一、算法原理
深度优先搜索算法是通过递归或使用栈(Stack)的数据结构来实现的。下面是深度优先搜索算法的详细步骤:
1. 选择起始节点,并标记该节点为已访问。
2. 从起始节点出发,依次访问与当前节点相邻且未被访问的节点。
3. 若当前节点有未被访问的邻居节点,则选择其中一个节点,将其标记为已访问,并将当前节点入栈。
4. 重复步骤2和3,直到当前节点没有未被访问的邻居节点。
5. 若当前节点没有未被访问的邻居节点,则从栈中弹出一个节点作为当前节点。
6. 重复步骤2至5,直到栈为空。
深度优先搜索算法会不断地深入到图或树的某一分支直到底部,然后再回退到上层节点继续搜索其他分支。因此,它的搜索路径类似于一条深入的迷宫路径,直到没有其他路径可走后,再原路返回。
二、代码实现
以下是使用递归方式实现深度优先搜索算法的代码:```python
def dfs(graph, start, visited):
visited.add(start)
print(start, end=" ")
for neighbor in graph[start]:
if neighbor not in visited:
dfs(graph, neighbor, visited)
C语言DFS(深度优先搜索算法)详解
C语言DFS(深度优先搜索算法)详解
DFS(深度优先)是一种用于遍历或图形或树结构的算法。它从起点
开始,沿着一条路径尽可能远地遍历图形,直到无法继续前进为止,然后
返回到上一个节点,探索其他路径。DFS基本上是一个递归的过程,它使
用栈来实现。
DFS的基本思想是递归地遍历图形。算法通过维护一个visited数组
来跟踪已经访问过的节点,以避免无限循环。首先,我们访问起点节点,
并将其标记为已访问。然后,对于起点的每个未访问的邻居节点,我们递
归地调用DFS。这样,我们沿着一条路径一直走到无法继续为止,然后返
回上一个节点继续探索其他未访问的邻居。我们重复这个过程,直到我们
访问了所有的节点。
在实现DFS时,我们需要用到一个栈来存储节点。首先,将起点节点
入栈。然后,当栈不为空时,我们将栈顶节点出栈,并将其标记为已访问。接下来,我们将栈顶节点的所有未访问邻居入栈。重复这个过程,直到栈
为空。需要注意的是,在使用栈时,我们应该按照相反的顺序将邻居节点
入栈,这样在出栈时才能按照正确的顺序进行访问。
DFS可以用来解决很多问题,例如图的连通性、寻找路径、生成所有
可能的子集等。对于连通性问题,如果我们可以从起点节点访问到所有的
节点,那么该图是连通的。对于寻找路径问题,我们可以使用DFS来找到
从起点到终点的路径。对于生成所有可能的子集问题,我们可以使用DFS
来枚举所有的子集。
下面是一个用C语言实现的DFS的示例代码:
```c
#include <stdio.h>
#define MAX_SIZE 10
int graph[MAX_SIZE][MAX_SIZE];
图的深度和广度优先遍历
数据结构课程实验报告
课程名称数据结构班级计算123 实验日期2014年6月1日--3日
姓名学号实验成绩实验名称实验四图的深度和广度优先遍历
实验目的及要求【实验目的】
熟练掌握图的邻接表存储结构及其图的建立方法和深度和广度优先遍历的方法。
【实验要求】
1.图的存储可采用邻接矩阵或邻接表
2.GraphCreate(): 按从键盘的数据建立图
3.GraphDFS():深度优先遍历图
4.GraphBFS():广度优先遍历图
5.编写完整程序完成下面的实验内容并上机运行
6.整理并上交实验报告
实验环境硬件平台:普通的PC机
软件平台:Windows 7 操作系统编程环境:VisualC++ 6.0
实验内容1.以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。
算法描述及实验步骤算法:
1)定义图的邻接表存储结构
2)实现图的邻接表存储,即建立图的存储结构
3)实现图的深度优先遍历
4)定义队列的顺序存储结构,并实现队列的基本操作如初始化队列、入队、出对、判断队列是否为空等。利用队列实现图的广度优先遍历。伪代码:
1)定义邻接矩阵和队列的存取结构;
2)创建图L:
1.置空图L->num=0;
2.输入顶点数目num;
3.i++,输入结点L->vexs[i]直到L->num;
3)输出图L的各顶点;
4)深度优先遍历图g中能访问的各个顶点
1.输入起点的下标qidian;
2.标志数组初始化mark[v]=0;
3.for(v=qidian;v<g.num+qidian;v++) //
图的遍历算法程序
//图的遍历算法程序 //图的遍历是指按某条搜索路径访问图中每个结点,使得每个结点均被访问一次,而且仅被访问一次。图的遍历有深度遍历算法和广度遍历算法,程序如下: #include //#include #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;iif(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;iprintf("输入顶点%d:",i);scanf("%c",&G.vexs[i]);temp=getchar(); //接收回车 }for(i=0;ifor(j=0;jG.arcs[i][j]=INFINITY;printf("输入%d条弧.\n",G.arcnum);for(i=0;iprintf("输入弧%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 && kfor(int i=0;iif(G.arcs[k][i]!=INFINITY) return i;}return -1;}//图G中顶点i的第j个邻接顶点的下一个邻接顶点int NextVex(Graph G,int i,int j){if(i>=0 && i=0 && jfor(int k=j+1;kif(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;iif(!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; //辅助队
浅析深度优先和广度优先遍历实现过程、区别及使用场景
浅析深度优先和⼴度优先遍历实现过程、区别及使⽤场景
⼀、什么是深度/⼴度优先遍历?
深度优先遍历简称DFS(Depth First Search),⼴度优先遍历简称BFS(Breadth First Search),它们是遍历图当中所有顶点的两种⽅式。
这两种遍历⽅式有什么不同呢?我们来举个栗⼦:
我们来到⼀个游乐场,游乐场⾥有11个景点。我们从景点0开始,要玩遍游乐场的所有景点,可以有什么样的游玩次序呢?
1、深度优先遍历
第⼀种是⼀头扎到底的玩法。我们选择⼀条⽀路,尽可能不断地深⼊,如果遇到死路就往回退,回退过程中如果遇到没探索过的⽀路,就进⼊该⽀路继续深⼊。在图中,我们⾸先选择景点1的这条路,继续深⼊到景点7、景点8,终于发现⾛不动了:
于是,我们退回到景点7,然后探索景点10,⼜⾛到了死胡同。于是,退回到景点1,探索景点9:
按照这个思路,我们再退回到景点0,后续依次探索景点2、3、5、4、发现相邻的都玩过了,再回退到3,再接着玩6,终于玩遍了整个游乐场:
具体次序如下图,景点旁边的数字代表探索次序。当然还可以有别的排法。
像这样先深⼊探索,⾛到头再回退寻找其他出路的遍历⽅式,就叫做深度优先遍历(DFS)。
这⽅式看起来很像⼆叉树的前序遍历。没错,其实⼆叉树的前序、中序、后序遍历,本质上也可以认为是深度优先遍历。
2、⼴度优先遍历
除了像深度优先遍历这样⼀头扎到底的玩法以外,我们还有另⼀种玩法:⾸先把起点相邻的⼏个景点玩遍,然后去玩距离起点稍远⼀些(隔⼀层)的景点,然后再去玩距离起点更远⼀些(隔两层)的景点…
无向图的深度优先和广度优先遍历
广度优先搜索算法pascal 算法框架
Program BFS;
初始化,存储初始状态(记录初始结点);
设队列首指针closed=0;队列尾指针open:=1;repeat
首指针closed后移一格,取其所指向的结点;
for r:=1 to max_r do
begin
if子结点符合条件且子结点没有重复扩展 then begin
尾指针open加1;把新结点存入队列尾;
记录相关信息;
if 达到目标 then 输出且结束;
end;
until closed>=open(队列空)
#define M 20
#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"
typedef struct{/*定义图*/
int V[M];
int R[M][M];
int vexnum;
}Graph;
void creatgraph(Graph *g,int n){/*创建图*/
int i,j,r1,r2;
g->vexnum=n;
for(i=1;i<=n;i++)/*顶点用i表示*/
{
g->V[i]=i;
}
for(i=1;i<=n;i++)/*初始化R*/
for(j=1;j<=n;j++)
{
g->R[i][j]=0;
}
printf("Please input R(0,0 END):\n");/*输入R*/ scanf("%d,%d",&r1,&r2);
while(r1!=0&&r2!=0)
{
g->R[r1][r2]=1;
g->R[r2][r1]=1;
scanf("%d,%d",&r1,&r2);
有向图的深度优先遍历
#include "stdio.h"
#include "stdlib.h"
int visited[20];
#define MAX_VERTER_NUM 20 typedef char VertexType;
typedef struct ArcNode{
int adjver;
struct ArcNode *nextarc;
//InfoType *info;
}ArcNode;
typedef struct VNode{
VertexType data;
ArcNode *firstarc;
}VNode,AdjList[MAX_VERTER_NUM]; typedef struct{
AdjList vertices;
int vexnum,arcnum;
int kind;
}ALGraph;
void GraphCreated(ALGraph *G) {
int i,j,n;
ArcNode *p,*q;
printf("请输入顶点个数和弧数:\n");
scanf("%d%d",&G->vexnum,&G->arcnum);
for(i=0;ivexnum;i++)
{
printf("请输入顶点名:\n");
scanf("%c",&G->vertices[i].data);
scanf("%c",&G->vertices[i].data);
G->vertices[i].firstarc=NULL;
printf("请输入该点关联顶点数:\n");
scanf("%d",&n);
if(n!=0)
printf("请输入该弧所指向顶点位置:\n");
图的广度优先遍历和深度优先遍历
#include
#include
#include
#define True 1
#define False 0
#define Error -1
#define Ok 1
#define INFINITY 0
#define MAX_VERTEX_NUM 10 //最大顶点数
#define MAX_EDGE_NUM 40 //最大边数
typedef enum {DG,DN,UDG,UDN}Graphkind;
typedef char VertexType; //顶点数据类型
typedef struct ArcCell
{
int adj; //无权图,1或0表示相邻否;带权图则是权值。
//int *info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct
{
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量AdjMatrix arcs; //邻接矩阵
int vexnum,arum; //图的当前顶点数和弧数。
Graphkind kind;
}MGraph;
typedef struct Arode
{
int adjvex;
int weight;
struct Arode *nextarc;
}Arode;
typedef struct VNode
{
int data;
Arode *firstarc;
}VNode,AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
深度优先遍历算法和广度优先遍历算法实验小结
深度优先遍历算法和广度优先遍历算法实验小结
一、引言
在计算机科学领域,图的遍历是一种基本的算法操作。深度优先遍历算法(Depth First Search,DFS)和广度优先遍历算法(Breadth First Search,BFS)是两种常用的图遍历算法。它们在解决图的连通性和可达性等问题上具有重要的应用价值。本文将从理论基础、算法原理、实验设计和实验结果等方面对深度优先遍历算法和广度优先遍历算法进行实验小结。
二、深度优先遍历算法
深度优先遍历算法是一种用于遍历或搜索树或图的算法。该算法从图的某个顶点开始遍历,沿着一条路径一直向前直到不能再继续前进为止,然后退回到上一个节点,尝试下一个节点,直到遍历完整个图。深度优先遍历算法通常使用栈来实现。以下是深度优先遍历算法的伪代码:
1. 创建一个栈并将起始节点压入栈中
2. 将起始节点标记为已访问
3. 当栈不为空时,执行以下步骤:
a. 弹出栈顶节点,并访问该节点
b. 将该节点尚未访问的邻居节点压入栈中,并标记为已访问
4. 重复步骤3,直到栈为空
三、广度优先遍历算法
广度优先遍历算法是一种用于遍历或搜索树或图的算法。该算法从图的某个顶点开始遍历,先访问起始节点的所有相邻节点,然后再依次访问这些相邻节点的相邻节点,依次类推,直到遍历完整个图。广度优先遍历算法通常使用队列来实现。以下是广度优先遍历算法的伪代码:
1. 创建一个队列并将起始节点入队
2. 将起始节点标记为已访问
3. 当队列不为空时,执行以下步骤:
a. 出队一个节点,并访问该节点
b. 将该节点尚未访问的邻居节点入队,并标记为已访问
广度优先遍历算法伪代码
1 . 初始化队列Q;
2. 访问顶点v; visited [v]=1; 顶点v入队Q;
3. while (队列Q非空)
3.1 v=队列Q的队头元素出队;
3.2 w=顶点v的第一个邻接点;
3.3 while (w存在)
3.3.1 如果w 未被访问,则
访问顶点w; visited[w]=1; 顶点w入队列Q;
3.3.2 w=顶点v的下一个邻接点;
图的深度优先遍历和广度优先遍历
华北水利水电学院数据结构实验报告
20 10 ~20 11 学年第一学期2008级计算机专业
班级:107学号:200810702姓名:王文波
实验四图的应用
一、实验目的:
1.掌握图的存储结构及其构造方法
2.掌握图的两种遍历算法及其执行过程
二、实验内容:
以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现无向连通图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。
提示:首先,根据用户输入的顶点总数和边数,构造无向图,然后以用户输入的顶点为起始点,进行深度优先和广度优先遍历,并输出遍历的结果。
三、实验要求:
1.各班学号为单号的同学采用邻接矩阵实现,学号为双号的同学采用邻接表实现。
2.C/ C++完成算法设计和程序设计并上机调试通过。
3.撰写实验报告,提供实验结果和数据。
4.写出算法设计小结和心得。
四、程序源代码:
#include
#define MaxVerNum 50
struct edgenode
{
int endver;
int inform;
edgenode* edgenext;
};
struct vexnode
{
char vertex;
edgenode* edgelink;
};
struct Graph
{
vexnode adjlists[MaxVerNum];
int vexnum;
int arcnum;
};
//队列的定义及相关函数的实现struct QueueNode
{
int nData;
QueueNode* next;
};
struct QueueList
{
QueueNode* front;
数据结构与算法(13):深度优先搜索和广度优先搜索
if (p1==-1 || p2==-1) {
System.out.printf("input error: invalid edge!\n");
return ;
}
mMatrix[p1][p2] = 1;
mMatrix[p2][p1] = 1;
}
}
/* * 创建图(用用已提供的矩阵)
*
* 参数说明:
int p2 = getPosition(edges[i][1]);
wenku.baidu.com
mMatrix[p1][p2] = 1;
mMatrix[p2][p1] = 1;
}
}
/* * 返回ch位置
*/
private int getPosition(char ch) {
for(int i=0; i<mVexs.length; i++)
if(mVexs[i]==ch)
return i;
return -1;
}
/* * 读取一一个输入入字符
*/
private char readChar() {
char ch='0';
do {
try {
ch = (char)System.in.read();
} catch (IOException e) {
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、实验目的
1.掌握图的各种存储结构,特别要熟练掌握邻接矩阵和邻接表存储结构;
2.遍历是图各种应用的算法的基础,要熟练掌握图的深度优先遍历和宽度优先遍历算法,复习栈和队列的应用;
3.掌握图的各种应用的算法:图的连通性、连通分量和最小生成树、拓扑排序、关键路径。
二、实验内容
实验内容1**图的遍历
[问题描述]
许多涉及图上操作的算法都是以图的遍历为基础的。写一个程序,演示在连通无向图上遍历全部顶点。
[基本要求]
建立图的邻接表的存储结构,实现无向图的深度优先遍历和广度优先遍历。以用户指定的顶点为起点,分别输出每种遍历下的顶点访问序列。
[实现提示]
设图的顶点不超过30个,每个顶点用一个编号表示(如果一个图有N个顶点,则它们的编号分别为1,2,…,N)。通过输入图的全部边输入一个图,每条边是两个顶点编号对,可以对边依附顶点编号的输入顺序作出限制(例如从小到大)。
[编程思路]
首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意无向是对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,深度遍历算法采用递归调用,其中最主要的是NextAdjVex(Graph G, int v, int w);FirstAdjVex ()函数的书写,依次递归下去,广度遍历用队列的辅助。
[程序代码]
头文件:
#include
#include
#define MAX_VERTEX_NUM 30
#define MAX_QUEUE_NUMBER 30
#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 struct ArcNode{
int adjvex; /*该边所指向的顶点的位置*/ struct ArcNode *nextarc; /*指向下一条边的指针*/ InfoType info; /*该弧相关信息的指针*/
}ArcNode;
/*定义顶点的结构*/
typedef struct VNode{
char data[40]; /*顶点信息*/
ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/
}VNode,AdjList[MAX_VERTEX_NUM];
/*定义图的结构*/
typedef struct {
AdjList vertices;
int vexnum,arcnum; /*图的当前顶点数和弧数*/
int kind; /*图的类型标志*/
}Graph;
/*定义队列的结构*/
typedef struct{
int *elem;
int front, rear;
}Queue;
/*功能选择*/
void MenuSelect(int w);
/*顶点定位*/
int LocateVex(Graph G,char *name);
/*创建无向图*/
void CreateGraph(Graph &G);
/*求第一个顶点*/
int FirstAdjVex(Graph G, int v);
/*求下一个顶点*/
int NextAdjVex(Graph G, int v, int w);
/*深度递归*/
void DFS(Graph G, int v) ;
/*深度遍历*/
void DFSTravel(Graph G,int v);
/*广度遍历*/
void BFSTraverse(Graph G,char *name);
/*初始化队列*/
Status InitQueue(Queue &Q);
/*判空*/
Status EmptyQueue(Queue Q);
/*进队*/
Status EnQueue(Queue &Q, int e);
/*出队*/
Status DeQueue(Queue &Q, int &e);
实现文件:
#include
#include"malloc.h"
#include "tuhead.h"
#include "stdlib.h"
#include "string.h"
bool visited[MAX_VERTEX_NUM];
/***********************************************************
* 顶点定位*
***********************************************************/
int LocateVex(Graph G,char *name)
{
int i;
for(i=1;i<=G.vexnum;i++) //从1号位置开始存储if(strcmp(name,G.vertices[i].data)==0) //相等则找到,返回位序return i;
return -1;
}
/***********************************************************
* 创建无向图*