图的两种遍历方式

图的遍历有两种:深度优先和广度优先。本文中,深度优先使用递归实现,每次递归找到第一个与当前结点相连且未输出过的结点继续往下递归,直至所有结点都已输出。广度优先将开始结点的所有邻接结点全部压入栈,当栈不为空时一直循环将栈首的结点的所有相邻结点压入栈。

具体代码实现如下:

  1 //邻接链表
  2 class Graph {
  3 private:
  4     //n: number of nodes
  5     int n;
  6     vector<int> *edges;
  7     bool *visited;
  8 public:
  9     Graph(int input_n) {
 10         n = input_n;
 11         edges = new vector<int>[n];
 12         visited=new bool[n];
 13         //size of bool=1
 14         memset(visited,0,n);
 15     }
 16     ~Graph() {
 17         delete[] edges;
 18         delete[] visited;
 19     }
 20     //no directions
 21     void insert(int x, int y) {
 22         edges[x].push_back(y);
 23         edges[y].push_back(x);
 24     }
 25
 26     //visited will be changed after one traversal
 27     //so need to reset for new operations
 28     void reset_visited(){
 29         memset(visited,0,n);
 30     }
 31
 32     void dfs(int vertex) {
 33         cout<<vertex<<endl;
 34         visited[vertex]=true;
 35         for(int adj_vertex: edges[vertex]){
 36             if(!visited[adj_vertex]){
 37                 dfs(adj_vertex);
 38             }
 39         }
 40     }
 41
 42     void bfs(int start_vertex) {
 43         queue<int> bfs_queue;
 44         bfs_queue.push(start_vertex);
 45         visited[start_vertex]=true;
 46         while(!bfs_queue.empty()){
 47             int vertex=bfs_queue.front();
 48             cout<<vertex<<endl;
 49             bfs_queue.pop();
 50             for(int adj_vertex: edges[vertex]){
 51                 //if it has not been put into the queue yet
 52                 if(!visited[adj_vertex]){
 53                     visited[adj_vertex]=true;
 54                     bfs_queue.push(adj_vertex);
 55                 }
 56             }
 57         }
 58     }
 59 };
 60
 61
 62
 63
 64 //邻接矩阵
 65 class Graph {
 66 private:
 67     //指向邻接矩阵
 68     int **mat;
 69     //n为顶点个数, 注意这里顶点是从0开始编号的
 70     int n;
 71     bool *visited;
 72 public:
 73     Graph(int input_n) {
 74         n = input_n;
 75         mat = new int *[n];
 76         for (int i = 0; i < n; ++i) {
 77             mat[i] = new int[n];
 78             memset(mat[i], 0, sizeof(int) * n);
 79         }
 80         visited=new bool[input_n];
 81         memset(visited,0,input_n);
 82     }
 83     ~Graph() {
 84         for (int i = 0; i< n; ++i) {
 85             delete[] mat[i];
 86         }
 87         delete[] mat;
 88         delete[] visited;
 89     }
 90     //flag=0为有向图, flag=1为无向图
 91     void insert(int x,int y, int flag){
 92         mat[x][y]=1;
 93         if(flag==1){
 94             mat[y][x]=1;
 95         }
 96     }
 97     void output() {
 98         for(int i=0;i<n;i++){
 99             for(int j=0;j<n;j++){
100                 cout<<mat[i][j]<<" ";
101             }
102             cout<<endl;
103         }
104     }
105
106     void reset_visited(){
107         memset(visited,0,n);
108     }
109
110     void dfs(int cur_vertex){
111         cout<<cur_vertex<<endl;
112         visited[cur_vertex]=true;
113         for(int adj_ver=0;adj_ver<n;adj_ver++){
114             if((!visited[adj_ver]) && mat[cur_vertex][adj_ver]==1){
115                 dfs(adj_ver);
116             }
117         }
118     }
119
120
121     void bfs(int start_vertex){
122         queue<int> bfs_queue;
123         bfs_queue.push(start_vertex);
124         visited[start_vertex]=true;
125         while(!bfs_queue.empty()){
126             int cur_ver=bfs_queue.front();
127             bfs_queue.pop();
128             cout<<cur_ver<<endl;
129             for(int adj_ver=0; adj_ver<n; adj_ver++){
130                 if((!visited[adj_ver]) && mat[cur_ver][adj_ver]==1){
131                     bfs_queue.push(adj_ver);
132                     visited[adj_ver]=true;
133                 }
134             }
135         }
136     }
137 };
时间: 2024-08-26 19:05:00

图的两种遍历方式的相关文章

邻接矩阵(以顶点为中心),比较稀疏时,采用邻接表;图的两种遍历(邻接矩阵实现)

对于边比较稠密的图,可以采用邻接矩阵(以顶点为中心)的方式表示,而边比较稀疏时,采用邻接表的结构更合适.两种都不能直观表达哪两个点相连或者最短路径是什么. 深度优先遍历类似于树的先根序遍历.与树不同的是,它需要对已经访问过的节点添加标记以免被重复遍历. public class Depth { /** * 对k号节点深度遍历 * @param a * @param color * @param k 节点 */ public static void depthTraversal(int[][] a

List集合中两种遍历方式

遍历List集合中的元素的方法有两种: 第一种:利用迭代器遍历 代码1: // 迭代器 Iterator it=list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } 或者代码2: for(Iterator it=list.iterator();it.hasNext();) { System.out.println(it.next()); }// 与while循环相比优点:对象it在循环结束后,变为垃圾,自动

Map的两种遍历方式

********************************************************************************* *****************************Map两种遍历方式******************************* ********************************************************************************* 1 package ccms;

图的两种遍历

两种遍历方法都使用了Visited[]这个数组来记录已经访问的节点 DFS(广度优先) 从头结点开始递归的来调用相邻的节点 void Visit( Vertex V ) { printf("正在访问顶点%d\n", V); } /* Visited[]为全局变量,已经初始化为false */ void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) ) { /* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */ PtrTo

Map集合的两种遍历方式

Map集合:即 接口Map<K,V> map集合的两种取出方式:    1.Set<k> keyset: 将map中所有的键存入到set集合(即将所有的key值存入到set中), 因为Set具备迭代器,可以进行迭代遍历. 所有可以迭代方式取出所有的链,再根据get方法.获取每一个键对应的值. Map 集合的取出原理: 将map集合转成set集合. 再通过迭代器取出    2. set<Map.Entry<k,v>>  entrySet: 将map集合中的映射

HashMap的两种遍历方式

HashMap存储的是键值对:key-value . java将HashMap的键值对作为一个整体对象(java.util.Map.Entry)进行处理,这优化了HashMap的遍历处理. 第一种:(只遍历一次,将key及value都放到entry中,效率高) Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { java.util.Map.Entry entry

Map两种遍历方式与TreeSet两种排序依据

集合:可以存储不同类型的多个对象,随着存储对象的个数的增加而自动扩大容量   体系结构: Collection<E>   |----List:存入的对象是有序的,且可以重复           ArrayList:底层使用的数据结构是数组,线程不安全的,查找速度快,增删速度慢           Vector:底层使用的数据结构是数组,线程安全的,查找速度快,增删速度慢           LinkedList:底层使用的数据结构是链表,线程不安全的,查找速度慢,增删速度快     |----

集合的两种遍历方式

① import java.util.ArrayList;import java.util.List; /* * List集合的特有遍历功能: *   size()和get()方法结合使用 */public class ListDemo2 { public static void main(String[] args) {  // 创建集合对象  List list = new ArrayList(); // 添加元素  list.add("hello");  list.add(&qu

图的两种遍历-DFS&amp;BFS

DFS和BFS在图中的应用: 图连通性判定:路径的存在性:图中是否存在环:求图的最小生成树:求图的关键路径:求图的拓扑排序. DFS:简单的说,先一直往深处走,直到不能再深了,再从另一条路开始往深处走,直到所有路都走完: struct node { int next; //E[i].next指向图中与i同父的下一个结点 int to; //E[i].to指向图中i的子结点 }E[110]; int N; int fa[110]; //记录各点的父结点 bool vis[110]; //记录这个点