圖之prim演算法

來源:互聯網
上載者:User

最小產生樹是資料結構中圖的一種重要應用,它的要求是從一個帶權無向完全圖中選擇n-1條邊並使這個圖仍然連通(也即得到了一棵產生樹),

同時還要考慮使樹的權最小。 prim演算法就是一種最小產生樹演算法。


普裡姆演算法的基本思想:

從連通網N={V,E}中的某一頂點U0出發,選擇與它關聯的具有最小權值的邊(U0,v),將其頂點加入到產生樹的頂點集合U中。以後每一步從一個頂點在U中,而另一個頂點不在U中的各條邊中選擇權值最小的邊(u,v),把它的頂點加入到集合U中。如此繼續下去,直到網中的所有頂點都加入到產生樹頂點集合U中為止。

下面舉例說明下prim演算法:

c語言實現如下:(使用鄰接矩陣儲存)

#include <stdio.h>#include <malloc.h>#define VERTEXNUM 6void createGraph(int (*edge)[VERTEXNUM], int start, int end, int value);void displayGraph(int (*edge)[VERTEXNUM]);void prim(int (*edge)[VERTEXNUM], int (**tree)[VERTEXNUM], int startVertex, int* vertexStatusArr);int main(void){//動態建立存放邊的二維數組          int (*edge)[VERTEXNUM] = (int (*)[VERTEXNUM])malloc(sizeof(int)*VERTEXNUM*VERTEXNUM);        int i,j;        for(i=0;i<VERTEXNUM;i++){                for(j=0;j<VERTEXNUM;j++){                        edge[i][j] = 0;                }        }//存放頂點的遍曆狀態,0:未遍曆,1:已遍曆         int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);        for(i=0;i<VERTEXNUM;i++){                vertexStatusArr[i] = 0;        }        printf("after init:\n");        displayGraph(edge);//建立圖          createGraph(edge,0,1,6);        createGraph(edge,0,3,5);        createGraph(edge,0,2,1);        createGraph(edge,1,2,5);        createGraph(edge,1,4,3);        createGraph(edge,2,4,6);        createGraph(edge,2,3,5);        createGraph(edge,2,5,4);        createGraph(edge,3,5,2);        createGraph(edge,4,5,6);        printf("after create:\n");        displayGraph(edge);//最小產生樹        int (*tree)[VERTEXNUM] = NULL;        prim(edge, &tree, 0, vertexStatusArr);        printf("after generate tree:\n");        displayGraph(tree);        free(edge);        free(tree);        return 0;}//建立圖void createGraph(int (*edge)[VERTEXNUM], int start, int end, int value){        edge[start][end] = value;        edge[end][start] = value;}//列印儲存的圖void displayGraph(int (*edge)[VERTEXNUM]){        int i,j;        for(i=0;i<VERTEXNUM;i++){                for(j=0;j<VERTEXNUM;j++){                        printf("%d ",edge[i][j]);                }                printf("\n");        }}void prim(int (*edge)[VERTEXNUM], int (**tree)[VERTEXNUM], int startVertex, int* vertexStatusArr){//申請儲存樹的記憶體        *tree = (int (*)[VERTEXNUM])malloc(sizeof(int)*VERTEXNUM*VERTEXNUM);        int i,j;        for(i=0;i<VERTEXNUM;i++){                for(j=0;j<VERTEXNUM;j++){                       (*tree)[i][j] = 0;                }        }//從頂點0開始,則頂點0就是已訪問的        vertexStatusArr[0] = 1;        int least, start, end, vNum = 1;//如果還頂點還沒有訪問完        while(vNum < VERTEXNUM){                least = 9999;                for(i=0;i<VERTEXNUM;i++){//選擇已經訪問過的點                        if(vertexStatusArr[i] == 1){                                for(j=0;j<VERTEXNUM;j++){//選擇一個沒有訪問過的點                                        if(vertexStatusArr[j] == 0){//選出一條value最小的邊                                                if(edge[i][j] != 0 && edge[i][j] < least){                                                        least = edge[i][j];                                                        start = i;                                                        end = j;                                                }                                        }                                }                        }                }                vNum++;//將點設定為訪問過                vertexStatusArr[end] = 1;//將邊加到樹中                createGraph(*tree,start,end,least);        }}

c語言實現如下:(使用鄰接表格儲存體)

#include <stdio.h>#include <malloc.h>#define VERTEXNUM 6//存放頂點的鄰接表元素typedef struct edge{        int vertex;        int value;        struct edge* next;}st_edge;void createGraph(st_edge** edge, int start, int end, int value);void displayGraph(st_edge** edge);void delGraph(st_edge** edge);void prim(st_edge** edge, st_edge*** tree, int startVertex, int* vertexStatusArr);int main(void){//動態建立存放邊的指標數組          st_edge** edge = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);        int i;        for(i=0;i<VERTEXNUM;i++){                edge[i] = NULL;        }//存放頂點的遍曆狀態,0:未遍曆,1:已遍曆          int* vertexStatusArr = (int*)malloc(sizeof(int)*VERTEXNUM);        for(i=0;i<VERTEXNUM;i++){                vertexStatusArr[i] = 0;        }        printf("after init:\n");        displayGraph(edge);//建立圖//從頂點0到頂點1的邊,值為6,一下類推        createGraph(edge,0,1,6);        createGraph(edge,0,3,5);        createGraph(edge,0,2,1);        createGraph(edge,1,2,5);        createGraph(edge,1,4,3);        createGraph(edge,2,4,6);        createGraph(edge,2,3,5);        createGraph(edge,2,5,4);        createGraph(edge,3,5,2);        createGraph(edge,4,5,6);        printf("after create:\n");        displayGraph(edge);        st_edge** tree = NULL;//從edge從中產生最小樹tree,從頂點0開始        prim(edge, &tree, 0, vertexStatusArr);        printf("after generate tree:\n");        displayGraph(tree);        delGraph(edge);        edge = NULL;        delGraph(tree);        tree = NULL;        free(vertexStatusArr);        vertexStatusArr = NULL;        return 0;}//建立圖void createGraph(st_edge** edge, int start, int end, int value){        st_edge* newedge1 = (st_edge*)malloc(sizeof(st_edge));        newedge1->vertex = end;        newedge1->value = value;        newedge1->next = NULL;        st_edge** edge1 = edge + start;        while(*edge1 != NULL){                edge1 = &((*edge1)->next);        }        *edge1 = newedge1;        st_edge* newedge2 = (st_edge*)malloc(sizeof(st_edge));        newedge2->vertex = start;        newedge2->value = value;        newedge2->next = NULL;        st_edge** edge2 = edge + end;        while(*edge2 != NULL){                edge2 = &((*edge2)->next);        }        *edge2 = newedge2;}//列印儲存的圖void displayGraph(st_edge** edge){        int i;        st_edge* p;        for(i=0;i<VERTEXNUM;i++){                printf("%d:",i);                p = *(edge+i);                while(p != NULL){                        printf("%d(%d) ",p->vertex,p->value);                        p = p->next;                }                printf("\n");        }}//釋放鄰接表佔用的記憶體void delGraph(st_edge** edge){        int i;        st_edge* p;        st_edge* del;        for(i=0;i<VERTEXNUM;i++){                p = *(edge+i);                while(p != NULL){                        del = p;                        p = p->next;                        free(del);                }                edge[i] = NULL;        }        free(edge);}//prim演算法void prim(st_edge** edge, st_edge*** tree, int startVertex, int* vertexStatusArr){//為最小產生樹申請記憶體        *tree = (st_edge**)malloc(sizeof(st_edge*)*VERTEXNUM);        int i,j;        for(i=0;i<VERTEXNUM;i++){                (*tree)[i] = NULL;        }//從頂點0開始,則頂點0就是已訪問的        vertexStatusArr[0] = 1;        st_edge* p;        int least, start, end, vNum = 1;//如果還頂點還沒有訪問完        while(vNum < VERTEXNUM){                least = 9999;                for(i=0;i<VERTEXNUM;i++){//選擇已經訪問過的點                        if(vertexStatusArr[i] == 1){                                for(j=0;j<VERTEXNUM;j++){//選擇一個沒有訪問過的點                                        if(vertexStatusArr[j] == 0){                                                p = *(edge+i);//選出一條value最小的邊                                                while(p != NULL){                                                        if(p->value < least && p->vertex == j){                                                                least = p->value;                                                                start = i;                                                                end = j;                                                        }                                                        p = p->next;                                                }                                        }                                }                        }                }                vNum++;//將點設定為訪問過                vertexStatusArr[end] = 1;//將邊加到樹中                createGraph(*tree,start,end,least);        }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.