最小生成树:数组
n个顶点,用n-1条边把一个连通图链接起来,而且使得权值和最小。ide
- /*
- *1.初始化两个数组,一个用于存放边权值,一个用来存放边权值的起始点
- *2.赋初值,从0开始,全部边权值都是和v0相关,全部边权值的起始点都是v0
- *3.大循环1到MG.numVertexes-1次
- *4.遍历边权值数组,找当前数组中的最小值,并将终点保存在k中
- *5.打印边
- *6.将加入的顶点的lowcost设置为0
- *7.使用新加入的顶点的邻接矩阵来更新lowcost数组和adjvex数组
- *
- *
- */
- void MiniSpanTree_Prim(MGraph MG){
- int min,i,j,k;
- int adjvex[MAXVEX];//存储与边对应的相关起始顶点
- int lowcost[MAXVEX];//存储顶点间边的权值
- lowcost[0] = 0;//权值为0表示此小标(V0)的顶点已经加入到了生成树中
- adjvex[0] = 0; //初始化第一个顶点的下标为0
- for(i=1;i<MG.numVertexes;i++){
- lowcost[i] = MG.arc[0][i];//将v0顶点相关的边的权值存储数组中
- adjvex[i] = 0;//这些边的起点都是v0,因此下标都是0
- }
- for(i=1;i<MG.numVertexes;i++){
- min = INFINITY;//最小权值初始化为无穷,一般将infinity设置为不可能的大数字
- j=1;k=0;
- while(j<MG.numVertexes){//在lowcost数组中寻找最小值,并记下最小值的终点存储在k中
- if(lowcost[j]!=0 && lowcost[j]<min){
- min = lowcost[j];
- k = j;
- }
- j++;
- }
- printf("(%d,%d)",adjvex[k],k);//打印边,起点和终点
- lowcost[k] = 0;//将当前顶点的权值设置为0,表示此顶点已经完成任务了
- for(j=1;j<MG.numVertexes;j++){//更新lowcost数组,使用刚添加进最小生成树的那个结点的行!
- if(lowcost[j]!=0 && MG.arc[k][j]<lowcost[j]){//若是下标为k的顶点各个边权值小于lowcost的边权值
- lowcost[j] = G.arc[k][j];//更新lowcost数组
- adjvex[j] = k;//更新与边权值相关联的边起点信息
- }
- }
- }
- }
- /*
- *1.定义一个边集,一个结点集,将结点集所有初始化为0,边集按照权的大小排列
- *2.循环边集中的每一条边,检查每条边的起点和终点,若是相同就继续循环,不然打印并修改parent
- *3.定义一个方法Find来寻找结点的走向
- *
- *
- *
- */
- typedef struct{
- int begin;
- int end;
- int weight;
- }Edge;
- void MiniSpanTree_Kruskal(MGraph MG,Edge edges[]){//此处使用元素类型为Edge的边集数组,已经按照权值由小到大排列
- int i,n,m;
- int parent[MAXVEX];//定义一数组用来判断边与边是否造成回路
- for(i=0;i<MG.numVertexes;i++){//初始化数组为0
- parent[i] = 0;
- }
- for(i=0;i<MG.numEdges;i++){//循环每一条边
- n = Find(parent,edges[i].begin);//
- m = Find(parent,edges[i].end);//
- if(n != m){//若是m、n不等说明此边没有与现有的生成树造成环路
- parent[n] = m;//数组下标记录了边起点,数组值记录了边终点
- printf("(%d,%d)%d",edges[i].begin,edges[i].end,edges[i].weight);
- }
- }
- }
- int Find(int *parent,int f){//查找从f这个坐标开始能走到的最远的结点是哪里
- while(parent[f]>0){//若是最后走到的最远的结点相同,说明是又环路生成的
- f = parent[f];
- }
- return f;
- }