資料結構學習總結--圖
擴張註釋為個人學習想法
兩種儲存結構—鄰接矩陣和鄰接表(理解演算法的前提,結構不清楚別看演算法)
1. 鄰接矩陣
//若只是為了建立二維陣列自然沒必要使用結構體定義,但往往還需要定義其頂點數和邊數等資訊
//此時使用結構體將其抽象為一個圖的資料結構就很有必要了(抽象大法好)
//先定義結點,因為結點自身可能會攜帶其他資訊
typedef struct {
int ind; //結點編號
int info; //其他資訊
}VType;
//定義鄰接矩陣
typedef struct{
int edges[maxSize][maxSIze]; //注意到這裡不是結點的二維陣列而是邊,若是有權圖改為float
int n,e; //結點數,邊數
VType vex[maxSize]; //節點資訊
}Mgraph; //Matrix of Graph
2.鄰接表
//先定義表所連邊,即從當前結點出發到下個結點的邊(弧尾為當前結點)
typedef struct ArcNode{
int ind; //對應鄰接表的下標而不是資料,這也是為什麼說這是邊的資料結構
stuct ArcNode *nextArc;
int w; //邊的權重
}ArcNode;
//表內元素,即圖結點
typedef struct VNode{ //其實個人更傾向於寫成adjNode,不過VNode在看圖時更清晰
int data; //資料
ArcNode *firstArc; //第一條邊
int i,o; //有需要的話定義出入度
}VNode;
//鄰接表
typedef struct {
VNode adjlist[maxSize];
int n,e; //頂點數和邊數
}AGraph; //Adjacent list of Graph
深度優先遍歷(DFS)
tips:利用遞迴儲存的特性使其在“搜尋”到最深處的時候可以順序回退,在其每次抵達結點時都需要對當前結點進行一個標記(很明顯即二叉樹先序遍歷思路,進入遞迴前visit()當前結點),需要設定一個全域性陣列visited()記錄一下結點的訪問資訊,防止二次訪問
int visited[maxSize]={0};
void DFS(AGrpah *G, int v){ //從v開始遍歷
ArcNode *p = G->adjlist[v].firstArc;
visited[v] = 1;
while(p!=NULL){
if(visited[p->ind]!=1) DFS(G, p);
p = p->nextArc;
}
把所有經歷的邊保留,其他刪去(可以在 visited[] 檢測為1時定義 q 記錄當前 p ,令 p 指向下一條邊後,釋放 q 所指邊),即可得到深度優先生成樹
廣度優先演算法(BFS)–類似於二叉樹層次遍歷
- 假定給的初始節點 v 是鄰接表的陣列下標,初始通過圖對應的鄰接表 G->adjlist[v].first 得到“第一條”邊(即 firstArc ),並用 p 記錄下該邊
- p->nextArc 迴圈遍歷同層結點,直至 p==NULL ,記錄下每次新頂點的下標至佇列 queue 中,並將對應 visited 置為1
- 設定front,rear指標分別指向隊頭隊尾以用於出入隊,當front==rear時佇列元素清空,遍歷完成
每次出隊的結點迴圈上述操作
void BFS(AGraph* G, int v, int visited[]){
memset(visited,0,maxSize); //初始化陣列
ArcNode* p;
int queue[maxSize], front = 0, rear = 0, j; //j為此時出隊結點
visit(); //visit()為對該結點操作函式,看情況進行定義
visited[v] = 1; //將初始結點標記已訪問
queue(rear++) = v; //佇列儲存的是下標,因為邊所定義的ind指向的是下標
while(front!=rear){ //沒使用迴圈佇列
p = G->adjlist[v].firstArc;
j = queue[front++]; //出隊
while(p!=NULL){ //層次遍歷
if(visited[p.ind]!=1){
visit();
queue[rear++] = p.ind; //將未訪問過的結點入隊
visited[p.ind] = 1; //標記已訪問
}
p = p->nextArc;
}
}
}
實際上以上 DFS 和 BFS 僅適用於連通分量(即極大連通子圖)只有一個的情況下,不過要適用多個非常簡單,外層套一個迴圈在發現 visited 值不為1時再次使用函式即可//以DFS為例,BFS一樣
void DFS_Traverse(Agraph *G){
for(int v=0;v<G.n;v++){
if(!visited[v]) DFS(G,v); //!visited[v]即visited[v]==0
}
}
相關文章
- 資料結構學習之樹結構資料結構
- 資料結構學習資料結構
- 資料結構與演算法學習總結--遞迴資料結構演算法遞迴
- 資料結構學習--連結串列資料結構
- 【資料結構】第六章學習小結--- 圖資料結構
- 資料結構學習心得資料結構
- 集合資料結構總結資料結構
- 資料結構 其五 樹與二叉樹學習總結資料結構二叉樹
- 重學資料結構(七、圖)資料結構
- 學習 JavaScript 資料結構(二)——連結串列JavaScript資料結構
- 資料結構學習筆記資料結構筆記
- SpringBoot學習之資料結構Spring Boot資料結構
- 資料結構 - 圖資料結構
- 學習javascript資料結構與演算法(六)——圖JavaScript資料結構演算法
- 演算法與資料結構學習路線圖演算法資料結構
- 【PHP資料結構】PHP資料結構及演算法總結PHP資料結構演算法
- 【資料結構——圖和圖的儲存結構】資料結構
- 資料結構總綱資料結構
- (資料結構程式碼,總結,自我思考)=> { return 個人學習筆記; } 【To be continued~】資料結構筆記
- 收藏資料結構學習網站資料結構學習網站
- 資料結構學習之佇列資料結構佇列
- 資料結構學習筆記1資料結構筆記
- 資料結構學習筆記--棧資料結構筆記
- JS資料結構學習:佇列JS資料結構佇列
- 資料結構之Stack | 讓我們一塊來學習資料結構資料結構
- 資料結構之Queue | 讓我們一塊來學習資料結構資料結構
- 資料結構之Set | 讓我們一塊來學習資料結構資料結構
- 資料結構之LinkedList | 讓我們一塊來學習資料結構資料結構
- 資料結構之圖資料結構
- 資料結構:圖(Graph)資料結構
- 如何學習資料結構和演算法——大佬文章彙總資料結構演算法
- Java 資料結構總結 (未完成)Java資料結構
- java資料結構學習之陣列Java資料結構陣列
- Redis 學習-資料結構基本簡介Redis資料結構
- 資料結構二叉樹學習資料結構二叉樹
- 資料結構學習筆記-堆排序資料結構筆記排序
- 關於資料結構的學習心得資料結構
- 20162319 2017-2018-20162319 《程式設計與資料結構》第10周學習總結程式設計資料結構