dfs與dfs遍歷圖節點

目錄

一、圖的存儲

1.1 鄰接矩陣

1.2 鄰接表

3.兩者區別

二、圖的深度遍歷(dfs)和廣度遍歷(bfs)---鄰接矩陣存儲

2.1 圖的深度遍歷(dfs)

2.2 圖的廣度遍歷(bfs)


一、圖的存儲

圖的存儲結構主要分兩種,一種是鄰接矩陣,一種是鄰接表。

1.1 鄰接矩陣

圖的鄰接矩陣存儲方式是用兩個數組來表示圖。一個一維數組存儲圖中頂點信息,一個二維數組(鄰接矩陣)存儲圖中的邊或弧的信息。
設圖G有n個頂點,則鄰接矩陣是一個n*n的方陣,定義爲:
這裏寫圖片描述
看一個實例,下圖左就是一個無向圖。
這裏寫圖片描述
從上面可以看出,無向圖的邊數組是一個對稱矩陣。所謂對稱矩陣就是n階矩陣的元滿足aij = aji。即從矩陣的左上角到右下角的主對角線爲軸,右上角的元和左下角相對應的元全都是相等的。
從上面可以看出,無向圖的邊數組是一個對稱矩陣。所謂對稱矩陣就是n階矩陣的元滿足aij = aji。即從矩陣的左上角到右下角的主對角線爲軸,右上角的元和左下角相對應的元全都是相等的。
從這個矩陣中,很容易知道圖中的信息。
(1)要判斷任意兩頂點是否有邊無邊就很容易了;
(2)要知道某個頂點的度,其實就是這個頂點vi在鄰接矩陣中第i行或(第i列)的元素之和;
(3)求頂點vi的所有鄰接點就是將矩陣中第i行元素掃描一遍,arc[i][j]爲1就是鄰接點;
而有向圖講究入度和出度,頂點vi的入度爲1,正好是第i列各數之和。頂點vi的出度爲2,即第i行的各數之和。
若圖G是網圖,有n個頂點,則鄰接矩陣是一個n*n的方陣,定義爲:這裏寫圖片描述

1.2 鄰接表

鄰接矩陣是不錯的一種圖存儲結構,但是,對於邊數相對頂點較少的圖,這種結構存在對存儲空間的極大浪費。因此,找到一種數組與鏈表相結合的存儲方法稱爲鄰接表。
鄰接表的處理方法是這樣的:
(1)圖中頂點用一個一維數組存儲,當然,頂點也可以用單鏈表來存儲,不過,數組可以較容易的讀取頂點的信息,更加方便。
(2)圖中每個頂點vi的所有鄰接點構成一個線性表,由於鄰接點的個數不定,所以,用單鏈表存儲,無向圖稱爲頂點vi的邊表,有向圖則稱爲頂點vi作爲弧尾的出邊表。
例如,下圖就是一個無向圖的鄰接表的結構。
這裏寫圖片描述
從圖中可以看出,頂點表的各個結點由data和firstedge兩個域表示,data是數據域,存儲頂點的信息,firstedge是指針域,指向邊表的第一個結點,即此頂點的第一個鄰接點。邊表結點由adjvex和next兩個域組成。adjvex是鄰接點域,存儲某頂點的鄰接點在頂點表中的下標,next則存儲指向邊表中下一個結點的指針。
對於帶權值的網圖,可以在邊表結點定義中再增加一個weight的數據域,存儲權值信息即可。如下圖所示。
這裏寫圖片描述

3.兩者區別

對於一個具有n個頂點e條邊的無向圖
它的鄰接表表示有n個頂點表結點2e個邊表結點
對於一個具有n個頂點e條邊的有向圖
它的鄰接表表示有n個頂點表結點e個邊表結點
如果圖中邊的數目遠遠小於n2稱作稀疏圖,這是用鄰接表表示比用鄰接矩陣表示節省空間;
如果圖中邊的數目接近於n2,對於無向圖接近於n*(n-1)稱作稠密圖,考慮到鄰接表中要附加鏈域,採用鄰接矩陣表示法爲宜。

 

二、圖的深度遍歷(dfs)和廣度遍歷(bfs)---鄰接矩陣存儲

輸入矩陣:

0 1 0 0 0 0 0 1 0 0
1 0 1 1 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 1 0 0 1 1 1 0 0 0
0 0 0 1 0 1 0 0 0 0
0 0 0 1 1 0 1 0 0 0
0 0 0 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 1 0 1
0 0 0 0 0 0 0 1 1 0

2.1 圖的深度遍歷(dfs)

1、從頂點v出發深度遍歷圖G的算法:① 訪問v, ② 依次從頂點v未被訪問的鄰接點出發深度遍歷。
2、一點心得:dfs算法最大特色就在於其遞歸特性,使得算法代碼簡潔。

2.2 圖的廣度遍歷(bfs)

1、從頂點v出發遍歷圖G的算法:
①訪問v,②假設最近一層的訪問頂點依次爲vi1,vi2,vi3...vik,則依次訪問vi1,vi2,vi3...vik的未被訪問的鄰接點
③重複②知道沒有未被訪問的鄰接點爲止

2、一點心得:bfs算法其實就是一種層次遍歷算法。從算法描述可以看到該算法要用到隊列這一數據結構。這裏用STL中的<queue>實現。

#include<iostream>
using namespace std;
 
int a[11][11];
bool visited[11];
 
void store_graph()  //鄰接矩陣存儲圖
{
    int i,j;
 
    for(i=1;i<=10;i++)
        for(j=1;j<=10;j++)
            cin>>a[i][j];
}
 
void dfs_graph()    //深度遍歷圖
{
    void dfs(int v);//dfs在該方法下面,所以需要定義
 
    memset(visited,false,sizeof(visited));
 
    for(int i=1;i<=10;i++)  //遍歷每個頂點是爲了防止圖不連通時無法訪問每個頂點
        if(visited[i]==false)
            dfs(i);
}
 
void dfs(int v)  //深度遍歷頂點
{
    int Adj(int x);//Adj在該方法下面,所以需要定義
 
    cout<<v<<" ";  //訪問頂點v
    visited[v]=true;
 
    int adj=Adj(v);
    while(adj!=0)
    {
        if(visited[adj]==false)   
            dfs(adj);      //遞歸調用是實現深度遍歷的關鍵所在
 
        adj=Adj(v);
    }
}
 
int Adj(int x)   //求鄰接點
{
    for(int i=1;i<=10;i++)
        if(a[x][i]==1 && visited[i]==false)
            return i;
 
    return 0;
}
 
int main()
{
    cout<<"初始化圖:"<<endl;
    store_graph();
 
    cout<<"dfs遍歷結果:"<<endl;
    dfs_graph();
 
    return 0;
}
#include<iostream>
#include<queue>    
using namespace std;
 
int a[11][11];
bool visited[11];
 
void store_graph()  
{
    for(int i=1;i<=10;i++)
        for(int j=1;j<=10;j++)
            cin>>a[i][j];
}
 
void bfs_graph()    
{
    void bfs(int v);
 
    memset(visited,false,sizeof(visited));
 
    for(int i=1;i<=10;i++)  
        if(visited[i]==false)
            bfs(i);
}
 
void bfs(int v)
{
    int Adj(int x);
 
    queue<int> myqueue;
    int adj,temp;
 
    cout<<v<<" ";
    visited[v]=true;
    myqueue.push(v);
 
    while(!myqueue.empty())    //隊列非空表示還有頂點未遍歷到
    {
        temp=myqueue.front();  //獲得隊列頭元素
        myqueue.pop();         //頭元素出對
 
        adj=Adj(temp);
        while(adj!=0)
        {
            if(visited[adj]==false)
            {
                cout<<adj<<" ";
                visited[adj]=true;
                myqueue.push(adj);   //進對
            }
 
            adj=Adj(temp);
        }
    }
}
 
int Adj(int x)   
{
    for(int i=1;i<=10;i++)
        if(a[x][i]==1 && visited[i]==false)
            return i;
 
    return 0;
}
 
int main()
{
    cout<<"初始化圖:"<<endl;
    store_graph();
 
    cout<<"bfs遍歷結果:"<<endl;
    bfs_graph();
 
    return 0;
}

 

 

轉自:圖的鄰接矩陣和鄰接表的比較      bfs與dfs

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章