日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【2019暑假刷题笔记-图的存储和图的遍历】绪论(代码模板-总结自《算法笔记》)

發(fā)布時(shí)間:2025/3/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【2019暑假刷题笔记-图的存储和图的遍历】绪论(代码模板-总结自《算法笔记》) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、圖的存儲(chǔ)

  • 圖有兩種存儲(chǔ)辦法,分別是鄰接矩陣(頂點(diǎn)數(shù)≤1000,0表示不連通,數(shù)字表示權(quán)重)和鄰接表(用vector數(shù)組實(shí)現(xiàn)),具體實(shí)現(xiàn)如下: /* 鄰接矩陣,G[][] */G[2][3]=1; //2和3連接(可以認(rèn)為權(quán)重為1) G[4][5]=0; //4和5不連接 G[7][8]=6; //7和8連接且權(quán)重為6 /* 鄰接表 vector<int> Adj[N]; */Adj[1].push_back(3); //1和3連接//鄰接表加權(quán)重 struct Node{int v; //邊的終點(diǎn)編號(hào)int w; //邊權(quán) }; vector<Node> Adj[N]; //這樣vector的鄰接表的類型就是Node了Node temp; temp.v=3; temp.w=4; Adj[1].push_back(temp);//鄰接表的另一種構(gòu)造 struct Node{int v,w;Node(int_v,int_w):v(_v),w(_w){}; //構(gòu)造函數(shù) };Adj[1].push_back(Node(3,4));
  • 以DFS法遍歷圖:

    /* 偽碼思想:不管是鄰接表還是鄰接矩陣都是采用這種辦法的(注:連通圖一次DFS解決) */ DFS(u){ //訪問定點(diǎn)uvis[u]=true; //設(shè)置u被訪問過了for(從u出發(fā)能到達(dá)的所有頂點(diǎn)v) //枚舉從u出發(fā)的所有頂點(diǎn)vif vis[v]==false //如果v沒有被訪問過DFS(v); }DFSTrave(G){ //遍歷Gfor(G的所有頂點(diǎn)u) //對(duì)G的所有頂點(diǎn)uif vis[u]==false //如果u未被訪問DFS(u); //訪問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已被訪問//如果需要對(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沒有被訪問且u可以達(dá)到vDFS(v,depth+1); //訪問v,深度加1}} }void DFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //對(duì)每個(gè)頂點(diǎn)uif(vis[u]==false){ //若u沒有被訪問過DFS(n,1); //訪問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)被訪問過了,則vis[i]==true.初值為falsevoid DFS(int u,int depth){ //u為當(dāng)前訪問的頂點(diǎn)標(biāo)號(hào),depth為深度vis[u]=true; //設(shè)置u已經(jīng)被訪問//如果需要對(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沒有被訪問過DFS(v,depth+1); //訪問v,深度+1}} }void DFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //對(duì)每個(gè)頂點(diǎn)uif(vis[u]==false){ //若u未被訪問DFS(u,1); //訪問u和u所在的聯(lián)通塊,1表示初始值為第一層}} }

    ?

  • 以BFS法遍歷圖:

    /* 偽碼思想 */ BFS(u){ //遍歷u所在的連通塊queue q;將u入隊(duì);inq[u]=true; //設(shè)置u已經(jīng)被加入過隊(duì)列while(q非空){ //只要隊(duì)列非空取出q的隊(duì)首元素u進(jìn)行訪問for(u出發(fā)可達(dá)的所有頂點(diǎn)v){ //枚舉從u所能直接到達(dá)的頂點(diǎn)vif(inq[v]==false){ //若v未曾加入過隊(duì)列將v入隊(duì)inq[v]=true; //設(shè)置v已被加入過隊(duì)列}}} }BFSTrave(){ //遍歷圖Gfor(G的所有頂點(diǎn)u) //枚舉G的所有頂點(diǎn)uif(inq[u]==false){ //若u未曾加入過隊(duì)列BFS(G); //遍歷u所在的連通塊} } /* 鄰接矩陣版 */ int n,G[MAXV][MAXV]; //n為頂點(diǎn)數(shù),MAXV為最大頂點(diǎn)數(shù) bool inq[MAXV]=false; //若頂點(diǎn)i曾入過隊(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)入過隊(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未曾加入過隊(duì)列q.push(v); //將v入隊(duì)inq[v]=true; //標(biāo)記v為已經(jīng)被加入過隊(duì)列}}} }void BFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //枚舉所有頂點(diǎn)if(inq[u]==false){ //若u未曾加入過隊(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曾入過隊(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)入過隊(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未曾加入過隊(duì)列q.push(v); //將v入隊(duì)inq[v]=true; //標(biāo)記v為已經(jīng)被加入過隊(duì)列}}} }void BFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //枚舉所有頂點(diǎn)if(inq[u]==false){ //若u未曾加入過隊(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曾入過隊(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)入過隊(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未曾加入過隊(duì)列q.push(next); //將next入隊(duì)inq[next.v]=true; //標(biāo)記next為已經(jīng)被加入過隊(duì)列}}} }void BFSTrave(){ //遍歷圖Gfor(int u=0;u<n;u++){ //枚舉所有頂點(diǎn)if(inq[u]==false){ //若u未曾加入過隊(duì)列BFS(q); //遍歷u所在連通塊}} }
  • ?

    總結(jié)

    以上是生活随笔為你收集整理的【2019暑假刷题笔记-图的存储和图的遍历】绪论(代码模板-总结自《算法笔记》)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。