1. 程式人生 > >prim演算法的實現過程

prim演算法的實現過程

為什麼要構建最小生成樹呢?其實原理很簡單。打個比方,現在某一個鄉鎮有n個村,那麼這n個村肯定是聯通的。現在我們打算在各個村之間搭建網線,實現村村通的工程。那麼有什麼辦法可以實現村村互通,同時又使得最後的總距離最小呢?要達到這個目的,就必須在已有的圖中構建最小生成樹。

    生成最小生成樹的方法很多,prim方法就是其中的一種。那麼生成最小生成樹的基本步驟是什麼呢?很簡單,聽我慢慢道來:

    1)以某一個點開始,尋找當前該點可以訪問的所有的邊;

    2)在已經尋找的邊中發現最小邊,這個邊必須有一個點還沒有訪問過,將還沒有訪問的點加入我們的集合,記錄新增的邊;

    3)尋找當前集合可以訪問的所有邊,重複2的過程,直到沒有新的點可以加入;

    4)此時由所有邊構成的樹即為最小生成樹。

     a)首先,我們定義基本的資料結構

  1. typedefstruct _DIR_LINE  
  2. {  
  3.     int start;  
  4.     int end;  
  5.     int weight;  
  6.     struct _DIR_LINE* next;  
  7. }DIR_LINE;  
  8. typedefstruct _MINI_GENERATE_TREE  
  9. {  
  10.     int node_num;  
  11.     int line_num;  
  12.     int* pNode;  
  13.     DIR_LINE* pLine;  
  14. }MINI_GENERATE_TREE;  

b)DIR_LINE的基本操作
  1. STATUS insert_line_into_queue(DIR_LINE** ppLine, int start, int end, int weight)  
  2. {  
  3.     DIR_LINE* pLine;  
  4.     if(NULL == ppLine)  
  5.         return FALSE;  
  6.     if(NULL == *ppLine){  
  7.         *ppLine = create_new_dir_line(start, end, weight);  
  8.         return TRUE;  
  9.     }  
  10.     pLine = create_new_dir_line(start, end, weight);  
  11.     pLine->next = *ppLine;  
  12.     *ppLine = pLine;  
  13.     return TRUE;  
  14. }  
  15. STATUS delete_line_from_queue(DIR_LINE** ppLine, DIR_LINE* pLine)  
  16. {  
  17.     DIR_LINE* prev;  
  18.     if(NULL == ppLine || NULL == *ppLine || NULL == pLine)  
  19.         return FALSE;  
  20.     if(pLine == *ppLine){  
  21.         *ppLine = pLine->next;  
  22.         goto final;  
  23.     }  
  24.     prev = *ppLine;  
  25.     while(pLine != prev->next)  
  26.         prev = prev->next;  
  27.     prev->next = pLine->next;  
  28. final:  
  29.     free(pLine);  
  30.     return TRUE;  
  31. }  

    前面我們討論了圖的建立、新增、刪除和儲存等問題。今天我們將繼續討論圖的一些其他問題,比如說如何在圖的環境下構建最小生成樹。為什麼要構建最小生成樹呢?其實原理很簡單。打個比方,現在某一個鄉鎮有n個村,那麼這n個村肯定是聯通的。現在我們打算在各個村之間搭建網線,實現村村通的工程。那麼有什麼辦法可以實現村村互通,同時又使得最後的總距離最小呢?要達到這個目的,就必須在已有的圖中構建最小生成樹。

    生成最小生成樹的方法很多,prim方法就是其中的一種。那麼生成最小生成樹的基本步驟是什麼呢?很簡單,聽我慢慢道來:

    1)以某一個點開始,尋找當前該點可以訪問的所有的邊;

    2)在已經尋找的邊中發現最小邊,這個邊必須有一個點還沒有訪問過,將還沒有訪問的點加入我們的集合,記錄新增的邊;

    3)尋找當前集合可以訪問的所有邊,重複2的過程,直到沒有新的點可以加入;

    4)此時由所有邊構成的樹即為最小生成樹。

     那麼,程式碼應該怎麼編寫呢?朋友們可以自己好好思考一下。

     a)首先,我們定義基本的資料結構

  1. typedefstruct _DIR_LINE  
  2. {  
  3.     int start;  
  4.     int end;  
  5.     int weight;  
  6.     struct _DIR_LINE* next;  
  7. }DIR_LINE;  
  8. typedefstruct _MINI_GENERATE_TREE  
  9. {  
  10.     int node_num;  
  11.     int line_num;  
  12.     int* pNode;  
  13.     DIR_LINE* pLine;  
  14. }MINI_GENERATE_TREE;  

b)DIR_LINE的基本操作
  1. STATUS insert_line_into_queue(DIR_LINE** ppLine, int start, int end, int weight)  
  2. {  
  3.     DIR_LINE* pLine;  
  4.     if(NULL == ppLine)  
  5.         return FALSE;  
  6.     if(NULL == *ppLine){  
  7.         *ppLine = create_new_dir_line(start, end, weight);  
  8.         return TRUE;  
  9.     }  
  10.     pLine = create_new_dir_line(start, end, weight);  
  11.     pLine->next = *ppLine;  
  12.     *ppLine = pLine;  
  13.     return TRUE;  
  14. }  
  15. STATUS delete_line_from_queue(DIR_LINE** ppLine, DIR_LINE* pLine)  
  16. {  
  17.     DIR_LINE* prev;  
  18.     if(NULL == ppLine || NULL == *ppLine || NULL == pLine)  
  19.         return FALSE;  
  20.     if(pLine == *ppLine){  
  21.         *ppLine = pLine->next;  
  22.         goto final;  
  23.     }  
  24.     prev = *ppLine;  
  25.     while(pLine != prev->next)  
  26.         prev = prev->next;  
  27.     prev->next = pLine->next;  
  28. final:  
  29.     free(pLine);  
  30.     return TRUE;  
  31. }