学习数据结构有两种常见的 邻接表 和 矩阵,矩阵太费空间, 表写起来很复杂
vector 优点:动态内存管理, 更节省空间
vector 的写法, 直接背模板就好啦
/* vector 无权无向图 4 4 1 4 4 2 2 3 3 1 DFS(1); 结果 1 4 2 3 */ #include<bits/stdc++.h> using namespace std; vector<int> v[105]; // 这里vector 实际上是一个动态二维数组 int vis[105]; // 遍历用的数组 void DFS(int start) { // 递归 cout << start << " "; vis[start] = 1; for ( int i = 0; i < v[start].size(); i++ ) { if ( vis[v[start][i]] == 0 ) { DFS(v[start][i]); } } return ; } int main() { int n, m; // n:节点个数 m:边数 cin >> n >> m; for ( int i = 1; i <= m; i++ ) { int a, b; cin >> a >> b; // 输入两个点连接的边, 以 a 为结点, b 为边 v[a].push_back(b); v[b].push_back(a); // 存无向图是, 需要把 b 连接到 a, 如果是存有向图, 删除这句 } return 0; }
前向星与 vector 相比, 空间优于 vector , 代码复杂度相似
前向星的写法 (前向星和 vector 都是邻接表的简化版, 在遇到图得问题是,从空间方面考虑,建议使用前向星, 因为vector 在申请内存时是默认开两倍的空间)
/* 前向星 无权无向图 + DFS 前向星就相当于是优化过后的 邻接表 */ #include<bits/stdc++.h> using namespace std; int vis[105]; // struct node { int to, next; // to : 边 //next : 指针 }p[105]; int tot = 1, head[105]; // 头节点, tot : 插入结点 void insert( int u, int v) { // u : 结点 v : 边 p[tot].to = v; p[tot].next = head[u]; head[u] = tot++; } void DFS(int start){ vis[start] = 1; cout << start << " "; for(int i = head[start];i != -1 ; i = p[i].next){ if(!vis[p[i].to]) DFS(p[i].to); } } int main() { memset(head,-1,sizeof(head)); int n, m; // 节点个数, 边数 cin >> n >> m; for ( int i = 1; i <= m; i++ ) { int a, b; cin >> a >> b; insert(a,b); insert(b,a); } DFS(1); return 0; }