最小生成树
来源:互联网 发布:数据挖掘 推荐系统 编辑:程序博客网 时间:2024/05/24 01:25
普利姆Prim算法就是层层遍历,一层一层的往下遍历找到最短的距离连接,标记组中巧妙的用 0 ,和 它的索引,高效的将所有值取到,将数组用到了极致。该算法一般常人想到的找最短距离一样,时间复杂度n^2
克鲁斯卡尔算法有所不一样,它设计了自己的结构体,在结构体数中有开始,结束,权。将线段所有的信息进行保留,然后按权排序,从最小的权开始往下选用点,建立一个数组用来查看是否有回路。时间复杂度eloge
对比俩个算法,克鲁斯卡尔算法主要是针对边来展开的。边数少的时候效率会非常高,对于稀疏图有很大的优势,而普利姆算法对于稠密图,即边数比较多的情况会好些
普利姆Prim算法
#include <iostream>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXEDGE 20#define MAXVEX 20#define INFINITY 65535using namespace std;typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef struct{ int arc[MAXVEX][MAXVEX]; int numVertexes, numEdges;}MGraph;void CreateMGraph(MGraph *G)/* 构件图 */{ int i, j; /* printf("请输入边数和顶点数:"); */ G->numEdges=15; G->numVertexes=9; for (i = 0; i < G->numVertexes; i++)/* 初始化图 */ { for ( j = 0; j < G->numVertexes; j++) { if (i==j) G->arc[i][j]=0; else G->arc[i][j] = G->arc[j][i] = INFINITY; } } G->arc[0][1]=10; G->arc[0][5]=11; G->arc[1][2]=18; G->arc[1][8]=12; G->arc[1][6]=16; G->arc[2][8]=8; G->arc[2][3]=22; G->arc[3][8]=21; G->arc[3][6]=24; G->arc[3][7]=16; G->arc[3][4]=20; G->arc[4][7]=7; G->arc[4][5]=26; G->arc[5][6]=17; G->arc[6][7]=19; for(i = 0; i < G->numVertexes; i++) { for(j = i; j < G->numVertexes; j++) { G->arc[j][i] =G->arc[i][j]; } }}/* Prim算法生成最小生成树 */void MiniSpanTree_Prim(MGraph G){ int min, i, j, k; int adjvex[MAXVEX]; /* 保存相关顶点下标 */ int lowcost[MAXVEX]; /* 保存相关顶点间边的权值 */ lowcost[0] = 0;/* 初始化第一个权值为0,即v0加入生成树 */ /* lowcost的值为0,在这里就是此下标的顶点已经加入生成树 */ adjvex[0] = 0; /* 初始化第一个顶点下标为0 */ for(i = 1; i < G.numVertexes; i++) /* 循环除下标为0外的全部顶点 */ { lowcost[i] = G.arc[0][i]; /* 将v0顶点与之有边的权值存入数组 */ adjvex[i] = 0; /* 初始化都为v0的下标 */ } for(i = 1; i < G.numVertexes; i++) { min = INFINITY; /* 初始化最小权值为∞, */ /* 通常设置为不可能的大数字如32767、65535等 */ j = 1;k = 0; while(j < G.numVertexes) /* 循环全部顶点 */ { if(lowcost[j]!=0 && lowcost[j] < min)/* 如果权值不为0且权值小于min */ { min = lowcost[j]; /* 则让当前权值成为最小值 */ k = j; /* 将当前最小值的下标存入k */ } j++; } cout << "(" << adjvex[k] << "," << k << ")" << endl;/* 打印当前顶点边中权值最小的边 */ lowcost[k] = 0;/* 将当前顶点的权值设置为0,表示此顶点已经完成任务 */ for(j = 1; j < G.numVertexes; j++) /* 循环所有顶点 */ { if(lowcost[j]!=0 && G.arc[k][j] < lowcost[j]) {/* 如果下标为k顶点各边权值小于此前这些顶点未被加入生成树权值 */ lowcost[j] = G.arc[k][j];/* 将较小的权值存入lowcost相应位置 */ adjvex[j] = k; /* 将下标为k的顶点存入adjvex */ } } }}int main(void){ MGraph G; CreateMGraph(&G); MiniSpanTree_Prim(G); return 0;}
克鲁斯卡尔算法
#include <iostream>using namespace std;#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */#define MAXEDGE 20#define MAXVEX 20#define INFINITY 65535typedef struct{ int arc[MAXVEX][MAXVEX]; int numVertexes, numEdges;}MGraph;typedef struct{ int begin; int end; int weight;}Edge; /* 对边集数组Edge结构的定义 *//* 构件图 */void CreateMGraph(MGraph *G){ int i, j; /* printf("请输入边数和顶点数:"); */ G->numEdges=15; G->numVertexes=9; for (i = 0; i < G->numVertexes; i++)/* 初始化图 */ { for ( j = 0; j < G->numVertexes; j++) { if (i==j) G->arc[i][j]=0; else G->arc[i][j] = G->arc[j][i] = INFINITY; } } G->arc[0][1]=10; G->arc[0][5]=11; G->arc[1][2]=18; G->arc[1][8]=12; G->arc[1][6]=16; G->arc[2][8]=8; G->arc[2][3]=22; G->arc[3][8]=21; G->arc[3][6]=24; G->arc[3][7]=16; G->arc[3][4]=20; G->arc[4][7]=7; G->arc[4][5]=26; G->arc[5][6]=17; G->arc[6][7]=19; for(i = 0; i < G->numVertexes; i++) { for(j = i; j < G->numVertexes; j++) { G->arc[j][i] =G->arc[i][j]; } }}/* 交换权值 以及头和尾 */void Swapn(Edge *edges,int i, int j){ int temp; temp = edges[i].begin; edges[i].begin = edges[j].begin; edges[j].begin = temp; temp = edges[i].end; edges[i].end = edges[j].end; edges[j].end = temp; temp = edges[i].weight; edges[i].weight = edges[j].weight; edges[j].weight = temp;}/* 对权值进行排序 */void sort(Edge edges[],MGraph *G){ int i, j; for ( i = 0; i < G->numEdges; i++) { for ( j = i + 1; j < G->numEdges; j++) { if (edges[i].weight > edges[j].weight) { Swapn(edges, i, j); } } } cout << "权排序之后的为:" << endl; for (i = 0; i < G->numEdges; i++) { cout << "(" << edges[i].begin << "," << edges[i].end <<")"<< " " << edges[i].weight << endl; }}/* 查找连线顶点的尾部下标 */int Find(int *parent, int f){ while ( parent[f] > 0) { f = parent[f]; } return f;}/* 生成最小生成树 */void MiniSpanTree_Kruskal(MGraph G){ int i, j, n, m; int k = 0; int parent[MAXVEX];/* 定义一数组用来判断边与边是否形成环路 */ Edge edges[MAXEDGE];/* 定义边集数组,edge的结构为begin,end,weight,均为整型 */ /* 用来构建边集数组并排序********************* */ for ( i = 0; i < G.numVertexes-1; i++) { for (j = i + 1; j < G.numVertexes; j++) { if (G.arc[i][j]<INFINITY) { edges[k].begin = i; edges[k].end = j; edges[k].weight = G.arc[i][j]; k++; } } } sort(edges, &G); /* ******************************************* */ for (i = 0; i < G.numVertexes; i++) parent[i] = 0; /* 初始化数组值为0 */ cout << "打印最小生成树:" <<endl; for (i = 0; i < G.numEdges; i++) /* 循环每一条边 */ { n = Find(parent,edges[i].begin); m = Find(parent,edges[i].end); if (n != m) /* 假如n与m不等,说明此边没有与现有的生成树形成环路 */ { parent[n] = m; /* 将此边的结尾顶点放入下标为起点的parent中。 */ /* 表示此顶点已经在生成树集合中 */ cout << "(" << edges[i].begin << "," << edges[i].end << ")" << " " << edges[i].weight << endl; } }}int main(void){ MGraph G; CreateMGraph(&G); MiniSpanTree_Kruskal(G); return 0;}
0 0
- 最小比例 最小生成树
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- 树+最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树Kruskal
- kruskal 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树问题
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- JavaScript中String(a)和new String(a)两种生成字符串的方法的使用区别
- CFgym:Ex Machina(交互 & 线段树区间最值)
- Hive 使用RegexSerDe来处理标准格式Apache Web日志
- java自定义注解实现对象到xml配置的转换
- 相机的功能丰富,加入前后摄像头的翻转,闪光灯,对焦功能。
- 最小生成树
- Java8新特性浅析
- Alsa框架录音程序
- 嵌入式工程师入门的那些
- HihoCoder
- TCP三次握手与四次挥手
- struts2初步使用及详解
- 基于qwertySearch和T9Search实现的通讯录
- 【第一次写解题报告,,激动】POJ 1125【弗洛伊德算法-floyd算法】