最小生成樹算法代碼


  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<iostream>
  4 #define MAX_VERTEX_NUM 20
  5 #define OK 1
  6 #define ERROR 0
  7 #define MAX 1000
  8 using namespace std;
  9 typedef struct Arcell
 10 {
 11     double adj;
 12 }Arcell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
 13 typedef struct
 14 {
 15     char vexs[MAX_VERTEX_NUM]; //節點數組
 16     AdjMatrix arcs; //鄰接矩陣
 17     int vexnum, arcnum; //圖的當前節點數和弧數
 18 }MGraph;
 19 typedef struct Pnode //用於普利姆算法
 20 {
 21     char adjvex; //節點
 22     double lowcost; //權值
 23 }Pnode,Closedge[MAX_VERTEX_NUM]; //記錄頂點集U到V-U的代價最小的邊的輔助數組定義
 24 typedef struct Knode //用於算法中存儲一條邊及其對應的2個節點
 25 {
 26     char ch1; //節點1
 27     char ch2; //節點2
 28     double value;//權值
 29 }Knode,Dgevalue[MAX_VERTEX_NUM];
 30 //-----------------------------------------------------------------------------------
 31 int CreateUDG(MGraph & G,Dgevalue & dgevalue);
 32 int LocateVex(MGraph G,char ch);
 33 int Minimum(MGraph G,Closedge closedge);
 34 void MiniSpanTree_PRIM(MGraph G,char u);
 35 void Sortdge(Dgevalue & dgevalue,MGraph G);
 36 //-----------------------------------------------------------------------------------
 37 int CreateUDG(MGraph & G,Dgevalue & dgevalue) //構造無向加權圖的鄰接矩陣
 38 {
 39     int i,j,k;
 40     cout<<"請輸入圖中節點個數和邊/弧的條數:";
 41     cin>>G.vexnum>>G.arcnum;
 42     cout<<"請輸入節點:";
 43     for(i=0;i<G.vexnum;++i)
 44         cin>>G.vexs[i];
 45     for(i=0;i<G.vexnum;++i)//初始化數組
 46     {
 47         for(j=0;j<G.vexnum;++j)
 48         {
 49             G.arcs[i][j].adj=MAX;
 50         }
 51     }
 52     cout<<"請輸入一條邊依附的定點及邊的權值:"<<endl;
 53     for(k=0;k<G.arcnum;++k)
 54     {
 55         cin >> dgevalue[k].ch1 >> dgevalue[k].ch2 >> dgevalue[k].value;
 56         i = LocateVex(G,dgevalue[k].ch1 );
 57         j = LocateVex(G,dgevalue[k].ch2 );
 58         G.arcs[i][j].adj = dgevalue[k].value;
 59         G.arcs[j][i].adj = G.arcs[i][j].adj;
 60     }
 61     return OK;
 62 }
 63 int LocateVex(MGraph G,char ch) //確定節點ch在圖G.vexs中的位置
 64 {
 65     int a ;
 66     for(int i=0; i<G.vexnum; i++)
 67     {
 68         if(G.vexs[i] == ch)
 69             a=i;
 70     }
 71     return a;
 72 }
 73 //typedef struct Pnode //用於普利姆算法
 74 //{
 75 //    char adjvex; //節點
 76 //    double lowcost; //權值
 77 //}Pnode,Closedge[MAX_VERTEX_NUM]; //記錄頂點集U到V-U的代價最小的邊的輔助數組定義
 78 void MiniSpanTree_PRIM(MGraph G,char u)//普利姆算法求最小生成樹
 79 {
 80     int i,j,k;
 81     Closedge closedge;
 82     k = LocateVex(G,u);
 83     for(j=0; j<G.vexnum; j++)
 84     {
 85         if(j != k)
 86         {
 87             closedge[j].adjvex = u;
 88             closedge[j].lowcost = G.arcs[k][j].adj;
 89         }
 90     }
 91     closedge[k].lowcost = 0;
 92     for(i=1; i<G.vexnum; i++)
 93     {
 94         k = Minimum(G,closedge);
 95         cout<<"("<<closedge[k].adjvex<<","<<G.vexs[k]<<","<<closedge[k].lowcost<<")"<<endl;
 96         closedge[k].lowcost = 0;
 97         for(j=0; j<G.vexnum; ++j)
 98         {
 99             if(G.arcs[k][j].adj < closedge[j].lowcost)
100             {
101                 closedge[j].adjvex = G.vexs[k];
102                 closedge[j].lowcost= G.arcs[k][j].adj;
103             }
104         }
105     }
106 }
107 int Minimum(MGraph G,Closedge closedge) //求closedge中權值最小的邊,並返回其頂點在vexs中的位置
108 {
109     int i,j;
110     double k = 1000;
111     for(i=0; i<G.vexnum; i++)
112     {
113         if(closedge[i].lowcost != 0 && closedge[i].lowcost < k)
114         {
115             k = closedge[i].lowcost;
116             j = i;
117         }
118     }
119     return j;
120 }
121 void MiniSpanTree_KRSL(MGraph G,Dgevalue & dgevalue)//克魯斯卡爾算法求最小生成樹
122 {
123     int p1,p2,i,j;
124     int bj[MAX_VERTEX_NUM]; //標記數組
125     for(i=0; i<G.vexnum; i++) //標記數組初始化
126         bj[i]=i;
127     Sortdge(dgevalue,G);//將所有權值按從小到大排序
128     for(i=0; i<G.arcnum; i++)
129     {
130         p1 = bj[LocateVex(G,dgevalue[i].ch1)];
131         p2 = bj[LocateVex(G,dgevalue[i].ch2)];
132         if(p1 != p2)
133         {
134             cout<<"("<<dgevalue[i].ch1<<","<<dgevalue[i].ch2<<","<<dgevalue[i].value<<")"<<endl;
135             for(j=0; j<G.vexnum; j++)
136             {
137                 if(bj[j] == p2)
138                     bj[j] = p1;
139             }
140         }
141     }
142 }
143 void Sortdge(Dgevalue & dgevalue,MGraph G)//對dgevalue中各元素按權值按從小到大排序
144 {
145     int i,j;
146     double temp;
147     char ch1,ch2;
148     for(i=0; i<G.arcnum; i++)
149     {
150         for(j=i; j<G.arcnum; j++)
151         {
152             if(dgevalue[i].value > dgevalue[j].value)
153             {
154                 temp = dgevalue[i].value;
155                 dgevalue[i].value = dgevalue[j].value;
156                 dgevalue[j].value = temp;
157                 ch1 = dgevalue[i].ch1;
158                 dgevalue[i].ch1 = dgevalue[j].ch1;
159                 dgevalue[j].ch1 = ch1;
160                 ch2 = dgevalue[i].ch2;
161                 dgevalue[i].ch2 = dgevalue[j].ch2;
162                 dgevalue[j].ch2 = ch2;
163             }
164         }
165     }
166 }
167 void main()
168 {
169     int i,j;
170     MGraph G;
171     char u;
172     Dgevalue dgevalue;
173     CreateUDG(G,dgevalue);
174     cout<<"圖的鄰接矩陣為:"<<endl;
175     for(i=0; i<G.vexnum; i++)
176     {
177         for(j=0; j<G.vexnum; j++)
178             cout << G.arcs[i][j].adj<<" ";
179         cout<<endl;
180     }
181     cout<<"=============普利姆算法===============\n";
182     cout<<"請輸入起始點:";
183     cin>>u;
184     cout<<"構成最小代價生成樹的邊集為:\n";
185     MiniSpanTree_PRIM(G,u);
186     cout<<"============克魯斯科爾算法=============\n";
187     cout<<"構成最小代價生成樹的邊集為:\n";
188     MiniSpanTree_KRSL(G,dgevalue);
189 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM