数据结构学习
学习参考:https://www.jianshu.com/p/70952b51f0c8
图的搜索一般有两种方式,一种是广度优先BFS,另一种是深度优先DFS
广度优先搜索在进一步遍历图中顶点之前,先访问当前顶点的所有邻接结点。
深度优先搜索在搜索过程中访问某个顶点后,需要递归地访问此顶点的所有未访问过的相邻顶点。
假设图的邻接矩阵如下
int Graph[5][5] = { { 0, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 1, 1, 1, 0 }, { 1, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 } };
BFS
#include <bits/stdc++.h> #define fi first #define se second #define pb push_back #define fio ios::sync_with_stdio(false);cin.tie(0); #define pii pair<int,int> #define vi vector<int> #define vc vector<char> #define fr front #define mii map<int,int> #define si(a) scanf("%d",&a) #define sl(a) scanf("%I64d",&a); #define slf(a) scanf("%lf",&a); #define pi acos(-1) const int INF=0x3f3f3f3f; const int N=2e5+5; typedef long long ll; typedef double db; typedef unsigned long long ull; using namespace std; int Graph[5][5] = { //也可以用vector的邻接表实现 { 0, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 1, 1, 1, 0 }, { 1, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 } }; int vis[N]; void BFS(int start) { queue<int> q; q.push(start); while(!q.empty()) { int fr=q.fr; cout<<q.fr<<" "; q.pop();//出队 for (int i=1;i<=5;i++)//5是边界 { if(!vis[i]&&Graph[fr-1][i-1])//如果自己没有被访问过并且上一个被访问到了 { vis[i]=1;//打上标记 q.push(i);//入队 } } } /* 以这张图为例 搜索1的可达点并打上标记,1出队2、3入队 搜索2的可达点并打上标记,2出队4入队 搜索3的可达点并打上标记,3出队 搜索4的可达点并打上标记,4出队,无入队 此时队列已空,结束,遍历一遍就知道哪个点不可达了 */ } int main() { fio;
memset(vis,0,sizeof(vis)); for (int i=1;i<=5;i++) { if(vis[i]) continue; else BFS(i); } }
DFS
DFS这里需要有回溯的思想,包括八皇后问题等等都是很典型的题目。
访问一个点后递归这个点所有的邻接点,直到没有邻接点为止,向上回溯
#include <bits/stdc++.h> #define fi first #define se second #define pb push_back #define fio ios::sync_with_stdio(false);cin.tie(0); #define pii pair<int,int> #define vi vector<int> #define vc vector<char> #define fr front #define mii map<int,int> #define si(a) scanf("%d",&a) #define sl(a) scanf("%I64d",&a); #define slf(a) scanf("%lf",&a); #define pi acos(-1) const int INF=0x3f3f3f3f; const int N=2e5+5; typedef long long ll; typedef double db; typedef unsigned long long ull; using namespace std; int Graph[5][5] = { //也可以用vector的邻接表实现 { 0, 1, 1, 0, 0 }, { 0, 0, 1, 1, 0 }, { 0, 1, 1, 1, 0 }, { 1, 0, 0, 0, 0 }, { 0, 0, 1, 1, 0 } }; int vis[N]; void DFS(int start) { vis[start]=1; for (int i=1;i<=5;i++) { if(!vis[i]&&Graph[start-1][i-1]==1) DFS(i); } cout<<start<<" "; } int main() { fio; for (int i=1;i<=5;i++) { if(vis[i]) continue; else DFS(i); } }
经过看了一些博客之后,感觉说懂都懂,但是用起来就很不顺手,该去做题了2333
DFS还有非递归的做法,在后面我会慢慢学习,先掌握最基础的再说
----------------------------------------------------------------------------------------------------------------------------------------
更新一波,贴一份dfs的模板
1 bool vis[N]; 2 int n; 3 4 void dfs(int x) 5 { 6 if()//判断是否越界 7 if()//判断是否满足条件,如果满足,ans++并且return 8 { 9 ans++; 10 return; 11 } 12 for (int i=1;i<=n;i++) 13 { 14 if()//判断是否满足继续下去的条件 15 { 16 vis[i]=1;//满足的话打标记 17 dfs(x+1);//继续dfs 18 vis[i]=0;//回溯 19 } 20 } 21 dfs(x+1);//继续dfs 22 }