数据结构——kruskal算法——最小生成树
首先应该理解kruskal算法思想:在连通图N=(V,{E})上,先建立一个初始状态为包含n个顶点而无边的非连通分图T=(V,{}),在边集E中找到权值最小的边,若此边的两个顶点落在T的不同的连通分量上,则将边加入T中,否则舍弃它而选择下一条代价小的边。以此类推,直到所有的顶点都落在同一连通分量上即可。
给出源码:
1 #include"iostream" 2 using namespace std; 3 4 #define MAX 1000 5 6 typedef struct ArcCell 7 { 8 double adj; 9 int *info; 10 }ArcCell,adjmatrix[100][100];//adj表示边的权值大小 11 12 typedef struct 13 { 14 char vexs[100]; 15 adjmatrix arcs; 16 int vexnum,arcnum;//图的顶点个数和弧度数 17 }MGraph;//以上均为用邻矩阵的储存结构定义图 18 19 typedef struct Node 20 {//建立一个储存两个顶点和它们之间权值大小的结构体 21 char start; 22 char end; 23 double value; 24 }Node,Dgevalue[100]; 25 26 int locatevex(MGraph G,char ch) 27 {//定位起始顶点ch在图中的位置 28 int k; 29 for(int i=0;i<G.vexnum;i++) 30 { 31 if(G.vexs[i]==ch) 32 k=i; 33 } 34 return k; 35 } 36 37 int creatmatrix(MGraph &G,Dgevalue &dgevalue) 38 {//构造邻接矩阵 39 int i,j,k; 40 cout<<"请输入顶点个数和弧度数"<<endl; 41 cin>>G.vexnum>>G.arcnum; 42 43 for(i=0;i<G.vexnum;i++)//读入顶点 44 cin>>G.vexs[i]; 45 46 for(i=0;i<G.vexnum;i++) 47 {//初始化边的权值为MAX 48 for(j=0;j<G.vexnum;j++) 49 { 50 G.arcs[i][j].adj=MAX; 51 } 52 } 53 cout<<"请输入一条边两端的定点及其上权值"<<endl; 54 for(k=0;k<G.arcnum;k++) 55 {//读入始终点及其上的权值value 56 cin>>dgevalue[k].start>>dgevalue[k].end>>dgevalue[k].value; 57 i=locatevex(G,dgevalue[k].start); 58 j=locatevex(G,dgevalue[k].end); 59 G.arcs[i][j].adj=dgevalue[k].value; 60 G.arcs[j][i].adj=G.arcs[i][j].adj; 61 } 62 return 0; 63 } 64 65 void sort(MGraph G,Dgevalue &dgevalue) 66 {//排序函数 67 char p1,p2; 68 int i,j,temp; 69 for(i=0;i<G.arcnum;i++) 70 {//快速排序 71 for(j=i;j<G.arcnum;j++) 72 { 73 if(dgevalue[i].value>dgevalue[j].value) 74 { 75 temp=dgevalue[i].value; 76 dgevalue[i].value=dgevalue[j].value; 77 dgevalue[j].value=temp; 78 79 p1=dgevalue[i].start; 80 dgevalue[i].start=dgevalue[j].start; 81 dgevalue[j].start=p1; 82 83 p2=dgevalue[i].end; 84 dgevalue[i].end=dgevalue[j].end; 85 dgevalue[j].end=p2; 86 } 87 } 88 } 89 } 90 91 void creatminitree_kruskal(MGraph G,Dgevalue &dgevalue) 92 {//kruskal 算法 93 int i,j,p[100]; 94 char pa,pb; 95 for(i=0;i<G.vexnum;i++) 96 p[i]=i; 97 98 sort(G,dgevalue); 99 cout<<endl; 100 for(i=0;i<G.arcnum;i++) 101 { 102 pa=p[locatevex(G,dgevalue[i].start)]; 103 pb=p[locatevex(G,dgevalue[i].end)]; 104 105 if(pa!=pb) 106 { //如果a、b不在同一连通分量中 107 cout<<dgevalue[i].start<<" "<<dgevalue[i].end<<" "<<dgevalue[i].value<<endl; 108 109 for(j=0;j<G.vexnum;j++) 110 {//让a、b位于同一连通分量中 111 if(p[j]==pb) 112 p[j]=pa; 113 114 } 115 } 116 } 117 } 118 119 int main() 120 { 121 char u; 122 MGraph G; 123 Dgevalue dgevalue; 124 creatmatrix(G,dgevalue); 125 cout<<"用kruskal算法求最小生成树"; 126 creatminitree_kruskal(G,dgevalue); 127 128 return 0; 129 }