图的存储方式有邻接矩阵和邻接表两种方式
深度优先搜索DFS
邻接矩阵
1. 邻接矩阵G[1][2]=INF 表示1->2两个节点无法访问
2. G[1][2]!=INF则表示1->2里面存放的是边权
const int MAXV=999;
const int INF = 999; //无穷大
int n , G[MAXV][MAXV];
bool vis[MAXV]={false} //访问true,没有访问false
void DFS(int u, int depth){
vis[u] = true //访问u,设置为true
//对u节点进行处理,遍历获取u节点的所有操作
for(int v = 0;v < n ; v++){ //v从0开始,遍历矩阵的第u行,第u行存储了节点u到其他节点(u-> v)的信息
if(vis[v]==false && G[u][v] != INF) //如果v没有被访问,并且u到v的距离不等于INF
{
DFS(v,depth+1);
}
}
}
void DFSTrave(){
for(int u = 0 ; u < n ; u++){
if(vis[u] == false){ // 如果u没有被访问过
DFS(u,1);
}
}
}
1.一共有n个顶点,用vis[MAXV]存储节点是否被访问过,遍历n个节点,如果节点没有被访问就DFS(u)
2.进入DFS(),立即设置vis[u]为true,紧接着遍历节点u可以到达的顶点,u可以到达的顶点信息在矩阵第u行
邻接表
1.邻接表 vector<int> Adj[N] 中第u行存储着u点可以到达的节点
2.引入
struct Node{
int v; //边的终点
int w; //边权
}存储终点编号和边权
vector<int> Adj[MAXV];
int n;
bool vis[AMXV]={false};
void DFS(int u , int depth){
vis[u] = =true
for(int i = 0 ; i < Adj[u].szie(); i++){
int v = Adj[i];
if(vis[v] == false){
DFS(v,depth+1);
}
}
void DFSTrave(){
for(int u = 0 ; u < n ;u++){
if(vis[u]==false){
DFS(u,1);
}
}
}
1.邻接矩阵里面使用vector<int > Adj[MAXV] 存储数据,第u行代表节点u可以到达的节点
需要引入struct来存储终点节点和边权
2.如果节点没有被访问过vis[u]==false ,就进行DFS
3.DFS() ,进入函数第一步就设置vis[u]=true,遍历邻接矩阵Adj[u].size(),依次判断v=Adj[u][v]是否访问过
广度优先搜索BFS
1.引入队列,先进先出,如果u可以到达的节点没有放入过队列,就将u放入队列。
2.如果队列不为空,就取出队列里面第一个节点,
邻接矩阵
int n , G[MAXV][MAXV];
bool inq[MAXV] = {false} //初始化,节点v都没有加入过队列
void BFS(int u){
queue<int> q;
q.push(u)
inq[u] = true ;
while(!q.empty()){
int u = q.front();
q.pop();
for(int v = 0 ,v < n ; v++){
if(G[u][v] !=INF && inq[v] == false){
q.push(v);
inq[v] = true;
}
}
}
}
void BFSTrave(){
for(int i = 0 ; i < n ; i++{
if(inq[i] == false) {
BFS(i)
}
}
}
邻接表
vector<int> Adj[MAXV];
int n;
bool inq[MAXV]={false}
void BFS(int u){
queue<int> q;
q.push(u);
inq[u] = true;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = 0 ,i < Adj[u].size() ; i++){
int v = Adj[u][i];
if(inq[v] == false){
q.push(v);
inq[v]=true;
}
}
}
}
void BFSTrave(){
for(int i = 0 ; i < n ; i++){
if(inq[i] == false){
BFS(i);
}
}
}