圖結構


介紹:

圖是一種復雜的非線性結構,圖型結構在每個節點中的元素關系是任意的,圖G由兩個集合V和E組成,定義G=(V,E),其中V是點的有限非空集合,E是由V的點表示的邊的集合。

對於圖G,可大致分成兩種方式,如果每條邊都有方向稱為有向圖,否則是無向圖。

在無向圖中存在一條邊表示(vi,vj),稱為邊的兩個端點,並稱為鄰接點,通常用n表示圖中的結點數,用e表示圖中邊的數,不考慮結點到自身的邊,任意結點都有邊相連就稱為完全無向圖,在有向圖中任意結點都有兩個相反的邊的稱為完全有向圖。

若在無向圖中,頂點和頂點之間存在一條路徑,如果路徑長度處了頂點和終點為同一頂點外,其余頂點均不相同稱為簡單路徑,若簡單路徑中起點和終點為同一頂點則稱為回路或環。圖中任意頂點之間存在路徑,則稱為連通圖。無向圖的極大連通子圖稱為連通分量。

在有向圖中,對任意兩個頂點之間互相有路徑,則稱為強連通圖,有向圖的極大連通子圖稱為強連通分量。

若在一個圖的每條邊上標上某種數字,稱為邊的全,邊上帶權的圖稱為帶權圖。

存儲結構:

常用兩種結構,鄰接矩陣和鄰接表。

鄰接矩陣是表示圖形頂點之間相鄰關系的矩陣。設G=(V,E)是具有n個頂點的圖,則G鄰接矩陣定義n階方陣:

A[i][j] = {1 若(vi,vj) 或 <vi,vj> 是G的邊},{0 若(vi,vj)或<vi,vj> 不是G的邊}

對於有向圖,可以有兩個矩陣,一個表示出邊,另一個入邊。由於無向圖的鄰接矩陣是對稱的,可以采用壓縮存儲元素。

鄰接表是圖的一種鏈式存儲結構。對於圖中G中的每個頂點vi,把所有的鄰接vi的頂點vj鏈接成一個單鏈表,稱為vi的鄰接表。

表中結點有兩個域:其一為鄰接點域(頂點),存儲與vi關系的vj的值,其二,為指針域,存儲下一個鄰接結點。在每一個鄰接頂點中存儲一個頂點域和鏈表指針來讀取圖。

圖的遍歷:

  深度優先遍歷類似樹的前序遍歷,假設圖的所有頂點沒有訪問過,則從圖的中的任意頂點為起始點,標記訪問過得頂點,然后依次遍歷每個鄰接點,直到起始點相通的頂點都被訪問,重復直到圖中所有頂點都被訪問。對圖進行深度優先遍歷時,按頂點的先后順序訪問的頂點稱為圖的深度優先遍歷序列。

  廣度優先搜索遍歷,類似樹的按層次遍歷,通過圖的層數來訪問頂點,先被訪問的頂點,其鄰接點也被訪問,符合隊列先進先出。所以算法需要隊列來記錄被訪問的頂點。

CirQueue Q;//隊列
    int k, j;
    InitQueue(Q);//初始化隊列
    printf("v%d->\n", i);//初始結點
    int visited[20];
    visited[i] = 1;//初始結點狀態
    EnQueue(Q, i);//結點入隊
    while (!QueueEmpty(Q)) {
        k = DeQueue(Q);//出隊
        for (j = 0; j < n; j++) {
            //如果當前鄰接矩陣到其它結點是否連通並且沒有被訪問過
            if (G.arcs[k][j] == 1 && !visited[j]) {
                printf("v%d->", j);
                visited[j] = 1;
                EnQueue(Q, j);//入隊
            }
        }
    }

圖的生成樹和最小生成樹:

在圖的表示中,一般樹定義為無回路的連通圖,一個連通圖的子圖如果是包含所有頂點的樹,稱為生成樹。生成樹是連通圖包含所有頂點的一個極小連通子圖(邊最少)。

最小生成樹,有權圖把生成樹各邊的權值總和稱為樹的權,把權值最小的生成樹稱為最小生成樹。

1.普里姆算法

   假設G=(V,G)是具有n個頂點的連通圖,T=(U,TE)是G的最小生成樹,其中U是T的頂點集,TE是T的邊集,U和TE的初值為空。

  (1)首先從V中任取一個頂點,將它放入U中,此時U={v1}。

  (2)U是V的真子集,在另一端的頂點在T外的所有邊中,找一條最短(權值最小)的邊,假定為(vi,vj),其中vi 屬於U,vj 屬於V-U,邊加入TE,vj頂點加入U

  (3)直到生成樹集合包含所有頂點,TE包含n-1邊,T就是最小生成樹。

2.克魯斯卡爾算法

  假設G=(V,E)是一個具有n個頂點的連通圖,T=(U,TE)是G的最小生成樹,U的初值等於V,包含有G的全部頂點。T的初始狀態包含n個頂點而無邊的森林T=(V,Ø),將圖G中的邊按權值從小到大依次選取E中的邊(u,v),若選取的邊使生成樹T不形成回路,則加入TE中,否則舍棄,如此進行直到TE中包含n-1邊,此時T為最小生成樹。

最短路徑:

Dijkstra提出按路徑長度遞增的順序產生頂點的最短路徑算法,算法思想設有向圖G=(V,E),其中V={1,2...n},cost表示G的鄰接矩陣,cost[i][j]表示有向邊<i,j>的權。若不存在<i,j>,則權為無窮大。設S是一個集合,其中每一個元素表示一個頂點,從源點到這些頂點的最短距離已經求出。設頂點v1是源點,集合S的初始只包含頂點v1。數組dist記錄源點到其它頂點當前最短距離,其初值為dist[i]=cost[v1][i],i=2...,n。從S之外的頂點集合V-S選出一個頂點w,使dist[w]的值最小。從源點到達w只通過S中的頂點,把w加入集合S中並調整dist記錄的從原點到V-S中每個頂點的距離,即從原來的dist[v]和dist[w]+cost[w][v]中選擇較小的值作為新的dist[v]。重復過程,直到S中包含V中其余頂點的最短路徑。


免責聲明!

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



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