目录
图的遍历
深度优先搜索法
广度优先搜索法
代码及注释部分
图的遍历,属于数据结构中的内容。指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次。图的遍历操作和树的遍历操作功能相似。图的遍历是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础之上。
由于图结构本身的复杂性,所以图的遍历操作也较复杂,主要表现在以下四个方面:
① 在图结构中,没有一个“自然”的首结点,图中任意一个顶点都可作为第一个被访问的结点。
② 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上的所有顶点,因此,还需考虑如何选取下一个出发点以访问图中其余的连通分量。
③ 在图结构中,如果有回路存在,那么一个顶点被访问之后,有可能沿回路又回到该顶点。
④ 在图结构中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,存在如何选取下一个要访问的顶点的问题。
图的遍历方法目前有深度优先搜索法和广度(宽度)优先搜索法两种算法。
深度优先搜索法
深度优先搜索法是树的先根遍历的推广,它的基本思想是:从图G的某个顶点v0出发,访问v0,然后选择一个与v0相邻且没被访问过的顶点vi访问,再从vi出发选择一个与vi相邻且未被访问的顶点vj进行访问,依次继续。如果当前被访问过的顶点的所有邻接顶点都已被访问,则退回到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点w,从w出发按同样的方法向前遍历,直到图中所有顶点都被访问。
广度优先搜索法
图的广度优先搜索是树的按层次遍历的推广,它的基本思想是:首先访问初始点vi,并将其标记为已访问过,接着访问vi的所有未被访问过的邻接点vi1,vi2,…, vi t,并均标记已访问过,然后再按照vi1,vi2,…, vi t的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依次类推,直到图中所有和初始点vi有路径相通的顶点都被访问过为止。
代码及注释部分
本代码分为四个部分,第一部分先定义一个图结构,第二部分建立邻接表,第三部分dfs深度优先搜索算法,第四部分bfs广度优先搜索算法,第五部分为主程序部分,调用各个函数。
#includeusing namespace std; const int MAX = 100;//顶点个数的最大值 //1、定义图的结构 typedef struct EdgeNode //弧节点结构 { int adjvex;//定义顶点域的位置 struct EdgeNode *next;//指向下一条弧的指针 }*edgeptr; typedef struct Vnode//顶点结点的结构 { int vertex; EdgeNode *link;//链域 }Adjlist[MAX];//最大100个 //2、定义邻接表 void build_adjlist(Adjlist& ga) { int n, e, i, j; EdgeNode *p, *q; cout << "请输入顶点数:"; cin >> n; //while (n<2) //{ //cout << "请重新输入!" << endl; //cin >> n; //} for (int m = 1; m <= n; m++)//初始化邻接表 { ga[m].vertex = m; ga[m].link = NULL; } cout << "请输入边数:"; cin >> e; for (int k = 0; k > i; cin >> j; p = new struct EdgeNode; p->adjvex = j; p->next = ga[i].link; ga[i].link = p; q = new struct EdgeNode; q->adjvex = i; q->next = ga[j].link; ga[j].link = q; } } //3、深度优先遍历:void dfs(Adjlist *g, int v0, int visited[]) void dfs(Adjlist g, int v0, int visited[]) {//从v0出发深度优先遍历图g,g以邻接表为储存结构 cout << v0; visited[v0] = 1;//标志v0已访问 EdgeNode *p; p = new EdgeNode; p = g[v0].link; while (p != NULL) { if (visited[p->adjvex] == 0) { dfs(g, p->adjvex, visited); } else p = p->next;//回溯,找v0的下一个邻接点 } } //4、广度优先遍历:void bfs(Adjlist *g, int v0, int visited[]) void bfs(Adjlist g, int v0, int visited[]) { int Q[MAX]; int v; int f, r;//f,r分别为队列的头尾指针 visited[v0] = 1; cout << v0; EdgeNode *p; p = new EdgeNode; p = g[v0].link; f = r = 0; do { while (p != NULL) { v = p->adjvex; if (visited[v] == 0)//若v未被访问,v入队 { r++; Q[r] = v; cout << v; visited[v] = 1; } p = p->next;//找某一个顶点的所有邻接点并进队 } if (f != r) { f++; v = Q[f]; p = g[v].link; } } while ((p != NULL) && (f != r)); } //5、主程序: void main() { Adjlist ga; build_adjlist(ga); int visited[MAX]; for (int i = 1; i <= MAX; i++) visited[i] = 0; cout << "深度优先遍历:" << endl; dfs(ga, 1, visited); cout << endl; for ( i = 1; i <= MAX; i++) visited[i] = 0; cout << "广度优先遍历:" << endl; bfs(ga, 1, visited); cout << endl; system("pause"); }
#本小白初入行不久,代码习惯必定是缺陷很多,欢迎各位大佬指正。



