圖論(Graph Theory)

ice_moss發表於2021-05-22

一、介紹

圖是用來對物件之間的成對關係建模的數學結構,由”節點”或”頂點”(Vertex)以及連線這些頂點的”邊”(Edge)組成。

圖論(Graph Theory)

值得注意的是,圖的頂點集合不能為空,但邊的集合可以為空。圖可能是無向的,這意味著圖中的邊在連線頂點時無需區分方向。否則,稱圖是有向的。

二、圖的分類

  1. 圖分為:無向圖和有向圖(無向圖是有向圖的特殊形式)
    無向圖:
    圖論(Graph Theory)

有向圖:
圖論(Graph Theory)

  1. 按權分為:無權圖和有權圖
    無權圖:
    圖論(Graph Theory)

有權圖:

圖論(Graph Theory)

  1. 圖有平行邊,自環邊:

圖論(Graph Theory)

三、圖的表示

  1. 鄰接矩陣:

    0——表示未連線 1——表示連線

  • 無向圖的鄰接矩陣:
    圖論(Graph Theory)
  • 有向圖的鄰接矩陣:
    圖論(Graph Theory)

適用說明:鄰接矩陣適合表示稠密圖

圖論(Graph Theory)

  1. 鄰接表:
  • 無向圖的鄰接表
    圖論(Graph Theory)
  • 有向圖的鄰接表
    圖論(Graph Theory)

適用說明:鄰接表適合表示稀疏圖

圖論(Graph Theory)

四、稠密圖、稀疏圖的實現(無權圖)

  1. 稠密圖的實現
    支援的操作有:
  • 返回節點數

  • 返回邊數

  • 向圖中新增邊

  • 驗證兩節點間是否有邊

  • 顯示圖的資訊

    #include <iostream>
    #include <vector>
    #include <cassert>
    using namespace std;
    //稠密圖
    class DenseGraph{
    private:
        int n, m; //節點數和邊數
        bool directed; //是否為有向圖
        vector<vector<bool>> g; //圖的具體資料,0 1 用bool值false和true表示
    public:
        DenseGraph(int n, bool directed){
          assert(n >= 0);
          this->n = n;
          this->m = 0;
          this->directed = directed;
    // g初始化為n*n的布林矩陣, 每一個g[i][j]均為false, 表示沒有任和邊
          g = vector<vector<bool>>(n, vector<bool>(n, false));
    }
      //解構函式
      ~DenseGraph(){}
    //返回圖中節點的個數
    int getV(){
         return n;
    }
    //返回圖中邊的條數
    int getE(){
         return m;
    }
    //向圖中新增一條邊
    void addEdga(int v, int w){
          assert(v >= 0 && v < n);
          assert(w >= 0 && w < n);
          if(hasEdga(v, w)){
               return;
           }
    
          g[v][w] = true;
        //無向圖是雙向的
          if(!directed){
               g[w][v] = true;
           }
          m++;
    }
    //驗證圖中是否有v到w的邊
    bool hasEdga(int v, int w){
         assert(v >= 0 && v < n);
         assert(w >= 0 && w < n);
         return g[v][w];
    }
    //顯示圖中資訊
    void show(){
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                cout<<g[i][j]<<"\t";
        cout<<endl;
         }
        }
      }
    };
  1. 稀疏圖的實現

支援的操作有:

  • 返回節點數

  • 返回邊數

  • 向圖中新增邊

  • 驗證兩節點間是否有邊

  • 顯示圖的資訊

    #include <iostream>
    #include <vector>
    #include <cassert>
    using namespace std;
    //稀疏圖—鄰接表
    class SparseGraph{
    private:
        int n, m; //節點數和邊數
        bool directed; //是否為無向圖
        vector<vector<int>> g; //圖的具體資料
    public:
       SparseGraph(int n,bool directed){
           assert(n >= 0);
           this->n = n;
           this->directed = directed;
           // g初始化為n個空的vector, 表示每一個g[i]都為空, 即沒有任和邊
           g = vector<vector<int>>(n, vector<int>());
    }
      //解構函式
      ~SparseGraph(){}
    
      int getV(){
          return n;
    }
      int getE(){
          return m;
    }
    // 向圖中新增一個邊
    void addEdga(int v, int w){
          assert( v >= 0 && v < n );
          assert( w >= 0 && w < n );
         //將w放入g[v][i]中,將w與v相連
          g[v].push_back(w);
          if(v != w && !directed){
              g[w].push_back(v);
          }
          m ++;
    }
    // 驗證圖中是否有從v到w的邊
    bool hasEdga(int v, int w){
          assert( v >= 0 && v < n );
          assert( w >= 0 && w < n );
          for(int i = 0; i <= g[v].size(); i++){
                if(g[v][i] == w)
                     return true;
                return false;  }
    }
    //顯示圖中資訊
    void show(){
        for(int i = 0; i < n; i++){
            cout<<"vector"<<":\t";
            for(int j = 0; j < g[i].size(); j++){
                cout<<g[i][j]<<":\t";
              }
            cout<<endl;
        }
      }
    };
    
    
    
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章