數據結構學習總結--圖


圖的定義

定義:圖是由兩個集合V和E組成的,記為\(G=(V,E)\),其中V是頂點的有窮非空集合,E是V中頂點偶對的有窮集合,這些頂點偶對稱為邊。\(V(G)\)\(E(G)\)通常表示圖G的頂點集合和邊集合,E(G)可以為空集 若E(G)為空 則圖G只有頂點而沒有邊。
有向圖:若邊集E(G)為有向邊的集合則稱該圖為有向圖;
無向圖:若邊集E(G)為無向邊的集合則稱該圖為無向圖;

有向圖的表示\(\color{red}{在有向圖中頂點對<x,y>是有序的}\) <x,y>與<y,x>是不同的兩條邊 頂點對用一對尖括號括起來,x是有向邊的始點,y是有向邊的終點,<x,y>也稱作一條弧,x為弧尾,y為弧頭。
無向圖的表示\(\color{red}{頂點對<x,y>是無序的}\),它稱為與頂點x與頂點y相關連的一條邊,無向圖的頂點對用一對圓括號表示。

圖的基本術語

(n表示圖中頂點數目,用表示邊的數目)
1.子圖:假設有兩個圖G=(V,E)和G'=(V',E'),如果V'包含於V且E'包含於E,則稱G'為G的子圖

2. 無向完全圖和有向完全圖:對於無向圖,若具有\(n*(n-1)/2\)條邊 則稱為無向完全圖。對於有向圖,若具有\(n*(n-1)\)條弧,則稱為有向完全圖。

  1. 稀疏圖和稠密圖:有很少條邊或弧的圖稱為稀疏圖,反之稱為稠密圖。

  2. 權和網:每條邊可以標上具有某種含義的數值,該數值稱為該邊上的權。這些權可以表示從一個頂點到另一個頂點的距離或耗費。這種帶權的圖稱為網。

  3. 鄰接點: 對於無向圖G,如果圖的邊(V,V')屬於E則稱頂點V和V'互為鄰接點,即V和V'相鄰接。

  4. 度,入度和出度:頂點V的度是指和V相關聯的邊的數目,記為TD(V)。 對於有向圖,頂點V的度分為入度和出度。入度是以頂點V為頭的弧的數目,記為ID(v);出度是以頂點V為尾的弧的數目,記為OD(v); 頂點的度為\(TD(V)=ID(V)+OD(V)\),一般地,如果頂點\({V_{i}}\)的度記為TD(\(V_{i}\)),那么一個有n個頂點,e條邊的圖滿足下列關系\(e=1/2*\sum\limits_{i=1}^{n}TD(V_{i})\)

  5. 路徑和路徑長度:在無向圖G中,從頂點V到頂點V'的路徑是一個頂點序列,如果G是有向圖則路徑也是有向的。路徑長度是一條路徑上經過邊或弧的數目。

  6. 回路或環:第一個頂點和最后一個頂點相同的路徑稱為回路或環。

  7. 簡單路徑,簡單回路或簡單環:序列中頂點不重復出現的路徑稱為簡單路徑,除了第一個頂點和最后一個頂點之外,其余頂點不重復出現的回路稱為簡單回路或簡單環。

  8. 連通,連通圖和連通分量:在無向圖G中,如果從頂點V到頂點V'有路徑,則稱V和V'是連通的,如果對於圖中任意兩個頂點都是連通的,則稱圖G是連通圖。所謂連通分量,指的是無向圖中的極大連通子圖。

  9. 極小連通子圖:該子圖是G的連通子圖,在該子圖中刪除任何一條子圖不再連通。

  10. 強連通圖和強連通分量:在有向圖G中,如果對於每一對的頂點都存在路徑則稱G是強連通圖。在有向圖中的極大強連通子圖稱作有向圖的強連通分量。

  11. 連通圖的生成樹:一個極小連通子圖,它含有圖中全部頂點,但只有足以構成一棵樹的n-1條邊,這樣的連通子圖稱為連通圖的生成樹。 一棵n個頂點的生成樹有且僅有n-1條邊。生成樹包含無向圖G所有頂點的極小連通子圖。生成樹所有頂點均由邊連接在一起,但不存在回路的圖。

  12. 有向樹和生成森林:有一個頂點的入度為0,其余頂點的入度均為1的有向圖稱為有向圖。一個有向圖的生成森林是由若干棵有向樹組成,含有圖中全部頂點,但只有足以構成若干棵不相交的有向樹的弧。

  13. 生成森林:對於非連通圖,由各個連通分量的生成樹的集合。


圖的存儲結構

圖沒有順序存儲結構,但可以借助二維數組來表示元素之間的關系,即鄰接矩陣表示法,圖的鏈式存儲方法:鄰接表,十字鏈表,鄰接多重表。

鄰接矩陣表示法



\(\color{red}{**有向圖和無向圖的鄰接矩陣的表示方法不同**}\)



其中\(W_{ij}\)為弧上的權值。


  `#define MaxInt 32767     //表示極大值,即無窮
   #define MVNum  100       // 最大頂點數
   typedef char VerTexType;    //假設頂點的數據類型為字符型
   typedef int ArcType;        //假設邊的權值類型為整型    
   typedef struct 
   { 
     VerTexType vexs[MVNum];   //頂點表
     ArcType arcs[MVNum][MVNum];   //鄰接矩陣
     int vexnum,arcnum;      //圖的當前點數和邊數
      }AMGraph;`




重點來了,重點是通過無向網稍微的更改變為無向圖和有向網

鄰接矩陣表示法的優缺點


缺點:①不方便增加和刪除頂點。②不便於統計邊的數目③空間復雜度高,鄰接矩陣表示法的空間復雜度均為\(O(n^2)\)


鄰接表

鄰接表是圖的一種鏈式存儲結構,鄰接表中每個單鏈表的第一個結點存放有關頂點的信息,把這個結點看成鏈表的表頭,其余結點存放有關邊的信息,這樣鄰接表便由兩部分組成:表頭結點表和邊表。
表頭結點表: 由所有表頭結點以順序結構的形式存儲,以便可以隨機訪問任一頂點的邊鏈表。表頭結點包括數據域(data)和鏈域(firstarc)兩部分,其中數據域用於存儲頂點\(V_{i}\)的名稱或其他信息;鏈域用於指向鏈表中第一個結點。
邊表:邊鏈表中邊結點包括鄰接點域(adjvex),數據域(info),和鏈域(nextarc)三部分,鄰接點域指示與頂點\(V_{i}\)鄰接的點在圖中的位置;數據域存儲和邊相關的信息如權值;鏈域指示與頂點\(V_{i}\)鄰接的下一條邊的結點。



  `///-----圖的鄰接表的存儲表示-------
     #define MVNum  100     //最大頂點數
     typedef struct ArcNode   //邊結點
     { 
      int adjvex;      //該邊所指向的頂點的位置
      struct ArcNode *nextarc    //指向下一條邊的指針
      OtherInfo info;    //和邊相關的信息
 }ArcNode;
 typedef struct VNode     //頂點信息
 {
   VerTexType data;
   ArcNode *firstarc;    //指向第一條依附該頂點的邊的指針
  }VNode,AdjList[MVNum];   //AdjList表示鄰接表類型
   typedef struct
    { 
     AdjList vertices;
     int vexnum,arcnum;    //圖的當前頂點數和邊數
   }ALGraph`


十字鏈表

十字鏈表是有向圖的另一種鏈式存儲結構 在弧結點中有五個域其中尾域(tailvex)頭域(headvex)分別指示弧尾和弧頭這兩個頂點在圖中的位置,鏈域hlink指向弧頭相同的下一條弧鏈域tlink指向弧尾相同的下一條弧info域指向該弧的相關信息。

鄰接多重表

鄰接多重表是無向圖的另一種鏈式存儲結構。mark是標志域可以標記該條邊是否被搜所過,ivexjvex為該邊依附的兩個頂點在圖中的位置,ilink指向下一條依附於頂點ivex的邊,jlink指向下一條依附於頂點jvex的邊,info域指向邊和邊的相關信息的指針域。


一些廢話吧最近剛開學,在家的狀態還沒有完全調整過來整個人完全不在狀態,情緒又上頭了 寫的不太好大家多擔待就這樣看吧。。。。。。。。。


深度優先遍歷

圖的遍歷是從圖中某一個頂點出發,按照某種方法對圖中所有頂點訪問且僅僅訪問一次。

深度優先遍歷(DFS)類似於樹的先序遍歷,對於一個連通圖,深度優先搜索遍歷的過程如下
(1)從圖中某個頂點V出發,訪問V
(2)找出剛訪問過的頂點的第一個未被訪問的鄰接點,訪問該頂點。以該頂點為新頂點,重復此步驟,直至剛訪問過的頂點沒有未被訪問的鄰接點為止。
(3)返回前一個訪問過的且仍有未被訪問的鄰接點的頂點,找出該頂點的下一個未被訪問的鄰接點,訪問該頂點。
(4)重復步驟(2)(3),直至圖中所有頂點都被訪問過,搜索結束。



解釋一下鄰接矩陣表示的無向圖深度遍歷:假設剛開始的起點為頂點2,輔助數組Visited[i]初始化為0,2為1;則開始選擇1進行遍歷此時Visited[1]等於0表示未被訪問過,則將其置於1,則從1開始依次遍歷,本身不能遍歷 則於頂點2遍歷,頂點2已經訪問則訪問一下個頂點3,此時頂點3的Visited[3]等於0表示未被訪問則將其置於1。則對3進行深度優先遍歷,頂點3訪問其鄰接點1已經訪問過了,訪問頂點5未被訪問將其Visited[5]置於1,則對5進行深度優先遍歷,結果是頂點2和頂點3已經訪問則回退一直回退到頂點1繼續訪問頂點四,依照上面步驟依次訪問就好。


稠密圖適用於在鄰接矩陣上進行深度遍歷
稀疏圖適用於在鄰接表上進行深度遍歷

時間復雜度

當用鄰接矩陣表示圖時,查找每個頂點的鄰接點的時間復雜度為O(\(n^2\)),其中n為頂點數,當以鄰接表做圖的存儲結構查找鄰接點的時間復雜度為O(e),其中e為邊數,由此當以鄰接表做存儲結構,深度優先遍歷圖的時間復雜度為O(n+e)


廣度優先遍歷

廣度優先遍歷(BFS)類似於樹的層次遍歷過程。


廣度優先遍歷(鄰接表表示的實現廣度優先遍歷)


廣度優先遍歷的解釋:初始化Visited[i]均為0且表示未被訪問,先將0號位置入隊,則0號位置一訪問置1,0號位置出隊訪問其鄰接點1,2則鄰接點1,2置1。將1,2入隊然后遍歷訪問1結點,0結點已經訪問則訪問3,4鄰接點將其置1,1結點出隊將3,4結點入隊;遍歷訪問2結點,0結點已經訪問則訪問5,6鄰接點將其置1,2結點出隊將5,6結點入隊;然后遍歷3結點,1結點以及訪問則訪問7鄰接點將其置1,3結點出隊將7結點入隊;此時所有結點都已經訪問,按照順序依次出隊即可。






最小生成樹



深度優先生成樹和廣度優先生成樹都是基於深度優先遍歷和廣度優先遍歷。

MST性質(一種貪心算法)

構造最小生成樹算法


普里目算法又稱為(加點法,在加點過程中不能成環即回路)

克魯斯卡爾算法實質上是選擇出權值最小的邊連接即可(注意不要成環)

最短路徑


習慣上我們稱路徑上第一個頂點為源點,最后一個頂點為終點
兩種最常見的最短路徑問題:一種是求某個源點到其余各頂點的最短路徑;另一種是求每一對頂點之間的最短路徑。

解決最短路徑的常見算法






拓撲排序



關鍵路徑






\(Ve(j)是事件最早開始時間=V(j)的起始結點的最早發生時間+各邊的權值中的和的最大值\)
\(Vl(i)是事件最晚開始時間是找權值之差的最小值\)
\(l(i)=e(i)\)時的活動\(a_{i}\)為關鍵活動。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM