數據結構圖(下)最小生成樹

最小生成樹

構造連通圖的最小代價生成樹

普里姆算法Prim

Prim算法用到的是鄰接矩陣,具體方法就是構造一個一維數組初始化值位一個特別大的數(再鄰接矩陣裏面就已經存好值了),然後從起始點開始找與之相連的點,並存到一維數組裏面;進行第一輪循環,找出相連點裏面權值最小的,標記這個最小值和點的下標,然後遍歷一維數組,找出與這個最小權值點相連的點,再把對於權值存到一維數組裏面,再重複上面的步驟,直到完全構成一個聯通圖。
代碼
//G是鄰接矩陣,n爲點數目

void Prim(int G[][],int n)
{
   int min,i,j;
   int a[1010];//存相關頂點下標
   int low [1010];//一維數組存權值
   low[0]=0;
   for(int i=1;i<n;i++)
   {
       low[i]=G[0][i];
       a[i]=0;
    }
    for(int i=1;i<n;i++)
    {
       min=-9999;
       j=1;
       k=0;
       while(j<n)
       {
       if(low[j]!=0&&low[j]<min)
       {
          min=j;k=j;
       }
       j++;
       }
       low[k]=0;
       for(j=1;j<n;j++)
       {
         if(!low[i]&&G[k][j]<min)
         {
         low[j]=G[k][j];
         a[j]=k;
         }
       }
    }
}

克魯斯卡爾算法Kruskal

Kruskal算法需要把鄰接矩陣先轉換爲一個邊集數組,就是按權值遞增順序存的一個結構體數組。在剩下的所有未選取的邊中,找最小邊,如果和已選取的邊構成迴路,則放棄,選取次小邊。

struct {
int s;
int e;
int weigh;
}Edge;
void Kruskal(int G[][],int n)
{
int i,n,m;
int parent[1001];
Edge edges[1010];
memset(parent,0,sizeof(a));
for(int i=0;i<n;i++)
{
n=Find(parent,edges[i].s);
m=Find(parent,edgs[i].e);
if(n!=m)
{
parent[n]=m;
printf("%d %d %d",edgs[i].s,edgs[i].e,edgs[i].weight);
}
}
}
int Find(int *parent,int f)
{
while(parent[f]>0)
f=parent[f];
return f;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章