【2019暑假刷题笔记-图的存储和图的遍历】绪论(代码模板-总结自《算法笔记》)
生活随笔
收集整理的這篇文章主要介紹了
【2019暑假刷题笔记-图的存储和图的遍历】绪论(代码模板-总结自《算法笔记》)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、圖的存儲(chǔ)
以DFS法遍歷圖:
/* 偽碼思想:不管是鄰接表還是鄰接矩陣都是采用這種辦法的(注:連通圖一次DFS解決) */ DFS(u){ //訪(fǎng)問(wèn)定點(diǎn)uvis[u]=true; //設(shè)置u被訪(fǎng)問(wèn)過(guò)了for(從u出發(fā)能到達(dá)的所有頂點(diǎn)v) //枚舉從u出發(fā)的所有頂點(diǎn)vif vis[v]==false //如果v沒(méi)有被訪(fǎng)問(wèn)過(guò)DFS(v); }DFSTrave(G){ //遍歷Gfor(G的所有頂點(diǎn)u) //對(duì)G的所有頂點(diǎn)uif vis[u]==false //如果u未被訪(fǎng)問(wèn)DFS(u); //訪(fǎng)問(wèn)u所在的連通塊 } /* 鄰接矩陣版DFS *///首先定義MAXV為最大頂點(diǎn)數(shù)、INF為一個(gè)很大的數(shù)字 const int MAXV=1000; const int INF=1000000000;int n,G[MAXV][MAXV]; //n為頂點(diǎn)數(shù),MAXV為最大頂點(diǎn)數(shù) bool vis[MAXV]={false}; void DFS(int u,int depth){vis[u]=true; //設(shè)置u已被訪(fǎng)問(wèn)//如果需要對(duì)u進(jìn)行一些操作,可以在這里進(jìn)行//下面對(duì)所有從u出發(fā)能到達(dá)的分支頂點(diǎn)進(jìn)行枚舉for(int v=0;v<n;v++){ //對(duì)每個(gè)頂點(diǎn)vif(vis[v]==false&&G[u][v]!=INF){ //如果v沒(méi)有被訪(fǎng)問(wèn)且u可以達(dá)到vDFS(v,depth+1); //訪(fǎng)問(wèn)v,深度加1}} }void DFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //對(duì)每個(gè)頂點(diǎn)uif(vis[u]==false){ //若u沒(méi)有被訪(fǎng)問(wèn)過(guò)DFS(n,1); //訪(fǎng)問(wèn)u和u所在的連通塊,1表示初試的第一層}} } /* 鄰接表版 */ const int MAXV=1000; vector<int> Adj[MAXV]; //圖G的鄰接表 int n; //n為頂點(diǎn)數(shù),MAXV為最大頂點(diǎn)數(shù) bool vis[MAXV]={false}; //若頂點(diǎn)i已經(jīng)被訪(fǎng)問(wèn)過(guò)了,則vis[i]==true.初值為falsevoid DFS(int u,int depth){ //u為當(dāng)前訪(fǎng)問(wèn)的頂點(diǎn)標(biāo)號(hào),depth為深度vis[u]=true; //設(shè)置u已經(jīng)被訪(fǎng)問(wèn)//如果需要對(duì)u進(jìn)行一些操作,可以在此處進(jìn)行for(int i=0;i<Adj[u].size();i++){ //對(duì)從u出發(fā)可以到達(dá)的所有頂點(diǎn)vint v=Adj[u][i];if(vis[v]==false){ //若v沒(méi)有被訪(fǎng)問(wèn)過(guò)DFS(v,depth+1); //訪(fǎng)問(wèn)v,深度+1}} }void DFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //對(duì)每個(gè)頂點(diǎn)uif(vis[u]==false){ //若u未被訪(fǎng)問(wèn)DFS(u,1); //訪(fǎng)問(wèn)u和u所在的聯(lián)通塊,1表示初始值為第一層}} }?
以BFS法遍歷圖:
/* 偽碼思想 */ BFS(u){ //遍歷u所在的連通塊queue q;將u入隊(duì);inq[u]=true; //設(shè)置u已經(jīng)被加入過(guò)隊(duì)列while(q非空){ //只要隊(duì)列非空取出q的隊(duì)首元素u進(jìn)行訪(fǎng)問(wèn)for(u出發(fā)可達(dá)的所有頂點(diǎn)v){ //枚舉從u所能直接到達(dá)的頂點(diǎn)vif(inq[v]==false){ //若v未曾加入過(guò)隊(duì)列將v入隊(duì)inq[v]=true; //設(shè)置v已被加入過(guò)隊(duì)列}}} }BFSTrave(){ //遍歷圖Gfor(G的所有頂點(diǎn)u) //枚舉G的所有頂點(diǎn)uif(inq[u]==false){ //若u未曾加入過(guò)隊(duì)列BFS(G); //遍歷u所在的連通塊} } /* 鄰接矩陣版 */ int n,G[MAXV][MAXV]; //n為頂點(diǎn)數(shù),MAXV為最大頂點(diǎn)數(shù) bool inq[MAXV]=false; //若頂點(diǎn)i曾入過(guò)隊(duì)列,則inq[i]==true。初值為falsevoid BFS(int u){ //遍歷u所在的連通塊queue<int> q; //定義隊(duì)列qq.push(u); //將初始點(diǎn)u入隊(duì)inq[u]=true; //設(shè)置u已經(jīng)進(jìn)入過(guò)隊(duì)列while(!q.empty()){ //只要隊(duì)列非空int u=q.front(); //取出隊(duì)首元素q.pop(); //將隊(duì)首元素出隊(duì)for(int v=0;v<n;v++){ if(inq[v]==false&&G[u][v]!=INF){ //若u的鄰接點(diǎn)v未曾加入過(guò)隊(duì)列q.push(v); //將v入隊(duì)inq[v]=true; //標(biāo)記v為已經(jīng)被加入過(guò)隊(duì)列}}} }void BFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //枚舉所有頂點(diǎn)if(inq[u]==false){ //若u未曾加入過(guò)隊(duì)列BFS(q); //遍歷u所在連通塊}} } /* 鄰接表版 */ vector<int> Adj[MAXV]; //圖G,Adj[u]存放從頂點(diǎn)u出發(fā)可以到達(dá)的所有頂點(diǎn) int n; //n為頂點(diǎn)數(shù),MAXV為最大頂點(diǎn)數(shù) bool inq[MAXV]={false}; //若頂點(diǎn)i曾入過(guò)隊(duì)列,則inq[i]==true。初值為falsevoid BFS(int u){ //遍歷u所在的連通塊queue<int> q; //定義隊(duì)列qq.push(u); //將初始點(diǎn)u入隊(duì)inq[u]=true; //設(shè)置u已經(jīng)進(jìn)入過(guò)隊(duì)列while(!q.empty()){ //只要隊(duì)列非空int u=q.front(); //取出隊(duì)首元素q.pop(); //將隊(duì)首元素出隊(duì)for(int i=0;i<Adj[u].size();i++){ //枚舉從u出發(fā)能到達(dá)的所有頂點(diǎn)int v=Adj[u][i]; if(inq[v]==false){ //若u的鄰接點(diǎn)v未曾加入過(guò)隊(duì)列q.push(v); //將v入隊(duì)inq[v]=true; //標(biāo)記v為已經(jīng)被加入過(guò)隊(duì)列}}} }void BFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //枚舉所有頂點(diǎn)if(inq[u]==false){ //若u未曾加入過(guò)隊(duì)列BFS(q); //遍歷u所在連通塊}} }?
/* 鄰接表版,設(shè)置層號(hào)和編號(hào) */ struct Node{int v;int layer; }vector<Node> Adj[MAXV]; //圖G,Adj[u]存放從頂點(diǎn)u出發(fā)可以到達(dá)的所有頂點(diǎn) int n; //n為頂點(diǎn)數(shù),MAXV為最大頂點(diǎn)數(shù) bool inq[MAXV]={false}; //若頂點(diǎn)i曾入過(guò)隊(duì)列,則inq[i]==true。初值為falsevoid BFS(int s){ //遍歷s為起編號(hào)queue<Node> q; //定義隊(duì)列qNode start;start.v=s;start.layer=0;q.push(start); //將初始點(diǎn)start入隊(duì)inq[start.v]=true; //設(shè)置start已經(jīng)進(jìn)入過(guò)隊(duì)列while(!q.empty()){ //只要隊(duì)列非空Node topNode=q.front(); //取出隊(duì)首元素q.pop(); //將隊(duì)首元素出隊(duì)int u=topNode.v; //隊(duì)首頂點(diǎn)的編號(hào)for(int i=0;i<Adj[u].size();i++){ //枚舉從u出發(fā)能到達(dá)的所有頂點(diǎn)int next=Adj[u][i]; next.layer=topNode.layer+1;if(inq[next.v]==false){ //若next的鄰接點(diǎn)v未曾加入過(guò)隊(duì)列q.push(next); //將next入隊(duì)inq[next.v]=true; //標(biāo)記next為已經(jīng)被加入過(guò)隊(duì)列}}} }void BFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //枚舉所有頂點(diǎn)if(inq[u]==false){ //若u未曾加入過(guò)隊(duì)列BFS(q); //遍歷u所在連通塊}} }?
總結(jié)
以上是生活随笔為你收集整理的【2019暑假刷题笔记-图的存储和图的遍历】绪论(代码模板-总结自《算法笔记》)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【堆】堆的基本操作总结
- 下一篇: 【计算机网络(微课版)】第5章 传输层