程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 一步一步寫算法(之圖結構)

一步一步寫算法(之圖結構)

編輯:關於C語言

 

【 聲明:版權所有,歡迎轉載,請勿用於商業用途。  聯系信箱:feixiaoxing @163.com】

 

 

 

 

     圖是數據結構裡面的重要一章。通過圖,我們可以判斷兩個點之間是不是具有連通性;通過圖,我們還可以計算兩個點之間的最小距離是多少;通過圖,我們還可以根據不同的要求,尋找不同的合適路徑。當然,有的時候為了計算的需要,我們還需要從圖中抽象出最小生成樹,這樣在遍歷計算的時候就不需要持續判斷是不是遇到了循環節點。當然,這所有的一切都是從圖的表示開始的。

 

    1)矩陣表示

 

    矩陣表示可以說是最簡單的表示方法,如果說一個圖中有5個點,那麼我們就可以構建一個5*5的矩陣。如果點和點之間存在連接,那麼填上1;反之如果不存在連接,那麼可以用0表示,當然對角線上面的點是沒有意義的。如下圖所示:

 

 

static int graph[5][5] =  

    {0, 1, 0, 1, 1}, 

    {1, 0, 1, 0, 1}, 

    {0, 1, 0, 1, 0}, 

    {1, 0, 1, 0, 1}, 

    {1, 1, 0, 1, 0} 

}; 

static int graph[5][5] =

{

       {0, 1, 0, 1, 1},

       {1, 0, 1, 0, 1},

       {0, 1, 0, 1, 0},

       {1, 0, 1, 0, 1},

       {1, 1, 0, 1, 0}

};    如果點和點之間還是存在方向的,那麼它們關於(x,x)對稱軸就是不對稱的,所以結果也可能是這樣的:

 

 

static int graph[5][5] =  

    {0, 0, 0, 0, 0}, 

    {1, 0, 0, 0, 0}, 

    {0, 1, 0, 0, 0}, 

    {1, 0, 1, 0, 0}, 

    {1, 1, 0, 1, 0} 

}; 

static int graph[5][5] =

{

       {0, 0, 0, 0, 0},

       {1, 0, 0, 0, 0},

       {0, 1, 0, 0, 0},

       {1, 0, 1, 0, 0},

       {1, 1, 0, 1, 0}

};    當然,如果點和點之間的關系存在某種權重,比如說距離,那我們可以用它來代替原來的數據1:

 

 

static int graph[5][5] =  

    {0, 0, 0, 0, 0}, 

    {3, 0, 0, 0, 0}, 

    {0, 6, 0, 0, 0}, 

    {8, 0, 4, 0, 0}, 

    {9, 2, 0, 7, 0} 

}; 

static int graph[5][5] =

{

       {0, 0, 0, 0, 0},

       {3, 0, 0, 0, 0},

       {0, 6, 0, 0, 0},

       {8, 0, 4, 0, 0},

       {9, 2, 0, 7, 0}

};

    矩陣表示下的圖結構非常直觀。但是,矩陣有一個特點,就是比較浪費空間。因為我們這裡舉例的頂點比較少,只有5個,但是請大家試想一下,如果一張圖上有10000個節點,那麼10000*10000該是多大的一個空間啊。重要的是,這10000*10000上面大多數點都是0,所以浪費的空間是相當可觀的。

 

 

 

 

    2)數組結構

 

    為了改變矩陣浪費空間的特點,我們可以建立一個只有頂點和邊組成的數據空間。比如說,我們定義一個這樣的結構:

 

 

typedef struct _LINE 

    int start; 

    int end; 

    int weight; 

    int isDirection; 

}LINE; 

typedef struct _LINE

{

       int start;

       int end;

       int weight;

       int isDirection;

}LINE;    上面定義的數據結構非常簡潔。第1個為起始頂點,第2個為終點,第3個為權重,第4個判斷當前邊是否有向。圖中要是有多少邊,我們就要定義多少個這樣的數據。如果把這些邊的數據都放在一起構成一個數組,那麼我們就可以用這個數組來表示圖的全部信息了。

 

    但是,我們還是覺得有遺憾的地方。這個數據結構過分強調了邊的意義和重要性,忽略了頂點本身的含義。因為,我們在強調邊的時候,應該添加進頂點的相關特性。離開頂點的支持,單純的邊信息是沒有什麼含義的。

 

 

 

 

    3)基於頂點鏈表的圖表示

 

    首先,我們定義頂點的基本結構:

 

 

typedef struct _LINE 

    int end; 

    int weight; 

    struct _LINE* next; 

}LINE; 

 

typedef struct _VECTEX 

    int start; 

    int number; 

    LINE* neighbor; 

}VECTEX; 

typedef struct _LINE

{

       int end;

       int weight;

       struct _LINE* next;

}LINE;

 

typedef struct _VECTEX

{

       int start;

       int number;

       LINE* neighbor;

}VECTEX;    我們用VECTEX記錄頂點的相關信息,LINE表示節點的相關信息。如果LINE是在VECTEX中的變量,那麼neighbor表示當前所有節點的起始點都是start點。如果它是PATH中的變量呢,那麼next的起始點就是LINE鏈接的前面一個點,不知道我講清楚了沒有?下面就是點與點之間PATH的定義。

 

 

typedef struct _PATH 

    int start; 

    int end; 

    int lenth; 

    LINE* next; 

}PATH; 

typedef struct _PATH

{

       int start;

       int end;

       int lenth;

       LINE* next;

}PATH;    其中start為起始點,end為終結點,next為start鏈接的下一個點,lenth為路徑的總長度,當然也可以修改成其他的權重形式。

 

注意事項:

 

    1)數組和鏈表是圖結構的基礎,朋友們應該好好掌握

 

    2)每一種數據結構都有自己的應用場合,關鍵是理解其中的思想和方法

 

    3)圖的表示是圖運算的基礎,掌握它們是我們進一步學習的基本條件

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved