图的深度和广度优先遍历
- 图的深度优先遍历
- 1、算法思想
- 2、邻接矩阵构造图
- 3、邻接表构造图
- 图的广度优先遍历
- 1、算法思想
- 2、邻接矩阵构造图
- 参考
图的深度优先遍历
1、算法思想
- (1)从图中的某个初始点 v 出发,首先访问初始点 v.
- (2)选择一个与顶点 v 相邻且没被访问过的顶点 ver ,以 ver为初始顶点,再从它出发进行深度优先遍历。
- (3)当路径上被遍历完,就访问上一个顶点的第 二个相邻顶点。
- (4)直到所有与初始顶点 v联通的顶点都被访问。
举例:
- 设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。
- 若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;
- 然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,
- 并且再选择一条从x出发的未检测过的边。上述过程直至从x出发的所有边都已检测过为止。
1.从0开始,首先找到0的关联顶点32.由3出发,找到1;由1出发,没有关联的顶点。3.回到3,从3出发,找到2;由2出发,没有关联的顶点。4.回到4,出4出发,找到1,因为1已经被访问过了,所以不访问。所以最后顺序是0,3,1,2,4
2、邻接矩阵构造图
#include <iostream>
#include <vector>using namespace std;#define VERTEXNUM 5void createGraph(vector<vector<int>>&edge, int start, int end);
void displayGraph(vector<vector<int>>&edge);
void DFS(vector<vector<int>>&edge , vector<int>& vertexStatusArr);
void DFScore(vector<vector<int>>&edge, int i, vector<int>& vertexStatusArr);int main(void) {//初始化邻接矩阵vector<vector<int>>edge(VERTEXNUM, vector<int>(VERTEXNUM, 0));//存放顶点的遍历状态,0:未遍历,1:已遍历 vector<int> vertexStatusArr (VERTEXNUM,0);cout << "after init: " << endl;displayGraph(edge);//创建图createGraph(edge, 0, 3);createGraph(edge, 0, 4);createGraph(edge, 3, 1);createGraph(edge, 3, 2);createGraph(edge, 4, 1);cout << "after create: " << endl;displayGraph(edge);//深度优先遍历DFS(edge, vertexStatusArr);return 0;
}
//创建图
void createGraph(vector<vector<int>>&edge, int start, int end) {edge[start][end] = 1;
}
//打印存储的图
void displayGraph(vector<vector<int>>&edge) {int i, j;for (i = 0; i<VERTEXNUM; i++) {for (j = 0; j<VERTEXNUM; j++) {//printf("%d ", edge[i][j]);cout << edge[i][j] << " ";}cout << endl;}
}
//深度优先遍历
void DFS(vector<vector<int>>&edge, vector<int>& vertexStatusArr) {cout << "start BFT graph: " << endl;for (int i = 0; i<VERTEXNUM; i++) {DFScore(edge, i, vertexStatusArr);}cout << endl;
}
void DFScore(vector<vector<int>>&edge, int i, vector<int>& vertexStatusArr) {if (vertexStatusArr[i] == 1) {return;}cout << i << " ";vertexStatusArr[i] = 1;for (int j = 0; j<VERTEXNUM; j++) {if (edge[i][j] == 1) {DFScore(edge, j, vertexStatusArr);}}
}
设有n个点,e条边
邻接矩阵:矩阵包含n ^2
个元素,在算法中,共n个顶点,对每个顶点都要遍历n次,所以时间复杂度为O(n^2)
3、邻接表构造图
#include <stdio.h>
#include <malloc.h>#define VERTEXNUM 5//存放顶点的邻接表元素
typedef struct edge {int vertex;struct edge* next;
}st_edge;void createGraph(st_edge** edge, int start, int end);
void displayGraph(st_edge** edge);
void delGraph(st_edge** edge);
void DFT(st_edge** edge, int* vertexStatusArr);
void DFTcore(st_edge** edge, int i, int* vertexStatusArr);int main(void) {//动态创建存放边的指针数组 st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);int i;for (i = 0; i<VERTEXNUM; i++) {edge[i] = NULL;}//存放顶点的遍历状态,0:未遍历,1:已遍历 int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);for (i = 0; i<VERTEXNUM; i++) {vertexStatusArr[i] = 0;}printf("after init:\n");displayGraph(edge);//创建图 createGraph(edge, 0, 3);createGraph(edge, 0, 4);createGraph(edge, 3, 1);createGraph(edge, 3, 2);createGraph(edge, 4, 1);printf("after create:\n");displayGraph(edge);//深度优先遍历 DFT(edge, vertexStatusArr);//释放邻接表占用的内存 delGraph(edge);edge = NULL;free(vertexStatusArr);vertexStatusArr = NULL;return 0;
}
//创建图
void createGraph(st_edge** edge, int start, int end) {st_edge* newedge = (st_edge*)malloc(sizeof(st_edge));newedge->vertex = end;newedge->next = NULL;edge = edge + start;while (*edge != NULL) {edge = &((*edge)->next);}*edge = newedge;
}
//打印存储的图
void displayGraph(st_edge** edge) {int i;st_edge* p;for (i = 0; i<VERTEXNUM; i++) {printf("%d:", i);p = *(edge + i);while (p != NULL) {printf("%d ", p->vertex);p = p->next;}printf("\n");}
}
//释放邻接表占用的内存
void delGraph(st_edge** edge) {int i;st_edge* p;st_edge* del;for (i = 0; i<VERTEXNUM; i++) {p = *(edge + i);while (p != NULL) {del = p;p = p->next;free(del);}edge[i] = NULL;}free(edge);
}
//深度优先遍历
void DFT(st_edge** edge, int* vertexStatusArr) {printf("start BFT graph:\n");int i;for (i = 0; i<VERTEXNUM; i++) {DFTcore(edge, i, vertexStatusArr);}printf("\n");
}void DFTcore(st_edge** edge, int i, int* vertexStatusArr) {if (vertexStatusArr[i] == 1) {return;}printf("%d ", i);vertexStatusArr[i] = 1;st_edge* p = *(edge + i);while (p != NULL) {DFTcore(edge, p->vertex, vertexStatusArr);p = p->next;}
}
邻接表:包含n个头结点和e个表结点,算法中对所有结点都要遍历一次,所以时间复杂度为O(n+e)
图的广度优先遍历
1、算法思想
广度优先遍历( Breadth_First_Search) ,又称为广度优先搜索,简称BFS。
它的思想是:
- 从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,
- 然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。
- 如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。
换句话说,广度优先搜索遍历图的过程是以v为起点,由近至远,依次访问和v有路径相通且路径长度为1,2…的顶点。
2、邻接矩阵构造图
#include <iostream>
#include <vector>
#include <queue>using namespace std;#define VERTEXNUM 5void createGraph(vector<vector<int>>&edge, int start, int end);
void displayGraph(vector<vector<int>>&edge);
void DFS(vector<vector<int>>&edge, vector<int>& vertexStatusArr);
void DFScore(vector<vector<int>>&edge, int i, vector<int>& vertexStatusArr);
void BFS(vector<vector<int>>&edge, vector<int>& vertexStatusArr);int main(void) {//初始化邻接矩阵vector<vector<int>>edge(VERTEXNUM, vector<int>(VERTEXNUM, 0));//存放顶点的遍历状态,0:未遍历,1:已遍历 vector<int> vertexStatusArr(VERTEXNUM, 0);cout << "after init: " << endl;displayGraph(edge);//创建图createGraph(edge, 0, 3);createGraph(edge, 0, 4);createGraph(edge, 3, 1);createGraph(edge, 3, 2);createGraph(edge, 4, 1);cout << "after create: " << endl;displayGraph(edge);//深度优先遍历//DFS(edge, vertexStatusArr);BFS(edge, vertexStatusArr);return 0;
}
//创建图
void createGraph(vector<vector<int>>&edge, int start, int end) {edge[start][end] = 1;
}
//打印存储的图
void displayGraph(vector<vector<int>>&edge) {int i, j;for (i = 0; i<VERTEXNUM; i++) {for (j = 0; j<VERTEXNUM; j++) {//printf("%d ", edge[i][j]);cout << edge[i][j] << " ";}cout << endl;}
}//BFS
void BFS(vector<vector<int>>&edge ,vector<int>& vertexStatusArr) {queue<int>q;q.push(0);vertexStatusArr[0] = 1;int idx = 0;while (!q.empty()){idx = q.front();q.pop();cout << idx << " ";for (int j = 0; j< VERTEXNUM; j++) {if (edge[idx][j] == 1 && vertexStatusArr[j] == 0){q.push(j);vertexStatusArr[j] = 1;}}}cout << endl;
}
参考
1、https://blog.csdn.net/todd911/article/details/9191481
2、https://blog.csdn.net/weixin_42109012/article/details/94199335
3、https://blog.csdn.net/Strive_Y/article/details/81810012?utm_medium=distribute.pc_relevant.none-task-blog-BlogCfData-2.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCfData-2.add_param_isCf
4、https://blog.csdn.net/weixin_40953222/article/details/80544928?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.add_param_isCf