Prim — 最小生成樹

Prim算法,普里姆算法,在無向圖中搜索最小生成樹。

算法實現的主要步驟:
(1) 初始化
所有點都初始化爲沒有被訪問,初始化根結點到各結點的距離,存放在lowcost[]數組中;

(2)尋找最小值
從根結點開始,其依據:一端連接,另一端未連接,尋找最小值
找到最小值後,更新lowcost[],未選結點到已選結點(可能已經選中了多個結點)中的最小值

(3)重複第(2)步,直到所有點都被選中,則算法結束。

本文依據下圖對算法實現:

這裏寫圖片描述


具體代碼如下,已經**在vs2010測試通過**。

#include <iostream>
using namespace std;

#define UndirectedGraphNode 6
#define INFINITE 1000

void Prim(int undirectedGraph[][UndirectedGraphNode], bool visited[], int lowcost[], int path[])
{
    //初始化
    memset(visited, 0, sizeof(bool) * UndirectedGraphNode);//所有點都沒有被訪問
    for(int i = 1; i < UndirectedGraphNode; i++)
        lowcost[i] = undirectedGraph[0][i];//根結點到各結點的距離

    //根結點被訪問
    int k = 0;//記錄加入路徑中的結點的順序
    visited[0] = true;
    path[k] = 0;//記錄加入路徑中的結點的下標
    int min;
    int minIndex;

    //一端連接,另一端未連接,尋找最小值
    for(int j = 1; j < UndirectedGraphNode; j++)//外層循環,每次循環確定一個點
    {
        min = INFINITE;//每次循環要重新賦值
        //尋找最小值
        for(int i = 1; i < UndirectedGraphNode; i++)
        {
            //存在多個條件的判斷,應將最可能爲假的條件放在前面,減少判斷次數
            if(false == visited[i] && lowcost[i] < min)
            {
                min = lowcost[i];
                minIndex = i;
            }
        }

        path[++k] = minIndex;//對應結點加入路徑中,區分 ++k 與 k++
        visited[minIndex] = true;//該點已經被訪問

        //更新lowcost[]
        //lowcost[],未選結點到已選結點中的最小值
        for(int i = 1; i < UndirectedGraphNode; i++)
        {
            if(false == visited[i] && lowcost[i] > undirectedGraph[minIndex][i])
                lowcost[i] = undirectedGraph[minIndex][i];
        }
    }
}

void PrimRun()
{
    //點與點之間存在邊,權重爲非零值,非無窮大值
    //點與點之間不存在邊,權重爲無窮大值
    int undirectedGraph[][UndirectedGraphNode] = 
    {
        {INFINITE, 12, INFINITE, INFINITE, 9, 9},
        {12, INFINITE, 6, INFINITE, INFINITE, 15},
        {INFINITE, 6, INFINITE, 3, INFINITE,  17},
        {INFINITE, INFINITE, 3, INFINITE, 4, 20},
        {9, INFINITE, INFINITE, 4, INFINITE,  9},
        {9, 15, 17, 20, 9, INFINITE},
    };

    bool visited[UndirectedGraphNode];
    int path[UndirectedGraphNode];
    int lowcost[UndirectedGraphNode];

    Prim(undirectedGraph, visited, lowcost, path);

    for(int i = 0; i < UndirectedGraphNode; i++)
        cout<<"v"<<path[i] + 1<<" ";//v1表示第一個結點
    cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    PrimRun();//調用
    return 0;
}

算法運行結果如圖所示:

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章