最小生成树之Prim算法实现
2016-06-07 21:03
441 查看
基本架构:先创建好一个邻接矩阵表示的图,然后按照prim算法思想找到最小生成树,注意将邻接矩阵表示的图在求最小生成树的时候转化为邻接表。
Prim 算法思想:
void Prim()
{
MST={V0};
while(1)
{
v=未收录顶点中dist最小的一个;
if(这样的v不存在)
break;
将v收录进MST中:dist[V]=0;
for(v的每个邻接点W)
{
if(dist[W]!=0)
if(E(v,w)<dist[W])
{
dist[W]=E(v,w);
parent[w]=v;
}
}
}
if(MST中的顶点个数小于|V|个)
cout<<"该图为非连通图!"<<endl;
}
代码实现:
Prim 算法思想:
void Prim()
{
MST={V0};
while(1)
{
v=未收录顶点中dist最小的一个;
if(这样的v不存在)
break;
将v收录进MST中:dist[V]=0;
for(v的每个邻接点W)
{
if(dist[W]!=0)
if(E(v,w)<dist[W])
{
dist[W]=E(v,w);
parent[w]=v;
}
}
}
if(MST中的顶点个数小于|V|个)
cout<<"该图为非连通图!"<<endl;
}
代码实现:
// Prim最小生成树实现.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<iostream> #include<stdio.h> #include<malloc.h> #define MaxVertexNum 100 #define INFINITY 50 using namespace std; typedef int Vertex; typedef int WeightType; typedef char DataType; //边的定义,适合邻接矩阵和邻接表 typedef struct ENode *PtrToENode; struct ENode { Vertex V1, V2; WeightType Weight; }; typedef PtrToENode Edge; //邻接矩阵表示的图的建立 typedef struct MGNode *PtrToMGNode; struct MGNode { int Nv;//顶点数 int Ne;//边数 WeightType G[MaxVertexNum][MaxVertexNum]; //邻接矩阵 DataType Data[MaxVertexNum];//顶点数组 }; typedef PtrToMGNode MGraph; //邻接表表示的图的结构体定义 //邻接点的定义 typedef struct AdjVNode *PtrToAdjVNode; struct AdjVNode { Vertex AdjV; //邻接点下标 WeightType Weight; //边权重 PtrToAdjVNode Next; //指向下一个邻接点的指针 }; //点表头结点的定义 typedef struct Vnode { PtrToAdjVNode FirstEdge; //边表头指针 DataType Data; //存顶点数据 }AdjList[MaxVertexNum]; //图结点的定义 typedef struct LGNode *PtrToLGNode; struct LGNode { int vexnum; int edgenum; AdjList G; //邻接表 }; typedef PtrToLGNode LGraph; int visited[MaxVertexNum];//标志数组 //函数声明 LGraph CreateLGraph(int Vertexnum); void InsertLEdge(LGraph Graph, Edge E); LGraph BuildLGraph(); void DFSTravel(LGraph Graph, Vertex V); //函数定义 LGraph CreateLGraph(int Vertexnum) {//初始化一个只有顶点,没有边的图 Vertex V; LGraph Graph; Graph = (LGraph)malloc(sizeof(struct LGNode)); Graph->vexnum = Vertexnum; Graph->edgenum = 0; for (V = 0; V<Graph->vexnum; V++) { Graph->G[V].FirstEdge = NULL; } return Graph; } void InsertLEdge(LGraph Graph, Edge E) { PtrToAdjVNode NewNode; //插入边<v1,v2> //为v2建立新的表结点 NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode->AdjV = E->V2; NewNode->Weight = E->Weight; NewNode->Next = Graph->G[E->V1].FirstEdge; Graph->G[E->V1].FirstEdge = NewNode; //若是无向图,还需插入边<v2,v1> //为v1建立新的结点 NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode->AdjV = E->V1; NewNode->Weight = E->Weight; NewNode->Next = Graph->G[E->V2].FirstEdge; Graph->G[E->V2].FirstEdge = NewNode; } LGraph BuildLGraph() { LGraph Graph; Edge E; Vertex V; int vexnum, i; std::cout << "请输入顶点个数:"; cin >> vexnum; Graph = CreateLGraph(vexnum); std::cout << "请输入边的个数:"; cin >> Graph->edgenum; if (Graph->edgenum != 0) { E = (Edge)malloc(sizeof(struct ENode)); for (i = 0; i<Graph->edgenum; i++) { cin >> E->V1 >> E->V2 >> E->Weight; InsertLEdge(Graph, E); } } //如果顶点有数据的话,读入数据 for (V = 0; V<Graph->vexnum; V++) cin >> Graph->G[V].Data; std::cout << "创建好的邻接表输出如下所示:" << endl; for (V = 0; V<Graph->vexnum; V++) { PtrToAdjVNode W; std::cout << Graph->G[V].Data << "的邻接点:"; for (W = Graph->G[V].FirstEdge; W; W = W->Next) { std::cout << W->AdjV << "," << Graph->G[W->AdjV].Data << "," << W->Weight << " "; } std::cout << endl; } return Graph; } //深度优先遍历图 /*void DFSTravel(LGraph Graph, Vertex V) { PtrToAdjVNode W; cout << Graph->G[V].Data; visited[V] = 1; for (W = Graph->G[V].FirstEdge; W; W = W->Next) if (!visited[W->AdjV]) DFSTravel(Graph, W->AdjV); }*/ //邻接矩阵表示的图的实现 MGraph CreateMGraph(int Vertexnum) {//初始化一个有Vertexnum个顶点但没有变得图 Vertex V, W; MGraph Graph; Graph = (MGraph)malloc(sizeof(struct MGNode)); Graph->Nv = Vertexnum; Graph->Ne = 0; for (V = 0; V<Graph->Nv; V++) { for (W = 0; W<Graph->Nv; W++) Graph->G[V][W] = INFINITY; //如果是有权无向图,应该是 //Graph->G[V][W] =Graph->G[W][V] = INFINITY; //如果是无权图有向图,可以初始化为0; //Graph->G[V][W] = 0; //如果是无权无向图,应该是 //Graph->G[V][W] =Graph->G[W][V] = 0; } return Graph; } void InsertMEdge(MGraph Graph, Edge E) {//插入边 Graph->G[E->V1][E->V2] = E->Weight; //若是无向图,则需要插入这条边 Graph->G[E->V2][E->V1] = E->Weight; //若是无权有向图, //Graph->G[E->V1][E->V2]=1; //若是无权无向图, ///Graph->G[E->V2][E->V1] = 1; } MGraph BuildMGraph() { MGraph Graph; Edge E; Vertex V; int i; int Nv; std::cout << "请输入顶点个数:"; cin >> Nv; Graph = CreateMGraph(Nv); std::cout << "请输入边的个数:"; cin >> Graph->Ne; if (Graph->Ne != 0) { E = (Edge)malloc(sizeof(struct ENode)); for (i = 0; i<Graph->Ne; i++) { cin >> E->V1 >> E->V2 >> E->Weight; //如果是无权图 //cin>>E->V1>>E->V2; InsertMEdge(Graph, E); } } for (V = 0; V<Graph->Nv; V++) cin >> Graph->Data[V]; Vertex W; std::cout << "创建好的邻接矩阵如下所示:" << endl; for (V = 0; V<Graph->Nv; V++) { for (W = 0; W < Graph->Nv; W++) std::cout << Graph->G[V][W] << " "; std::cout << endl; } return Graph; } Vertex FindMinDist(MGraph Graph, WeightType dist[]) { Vertex MinV, V; WeightType MinDist = INFINITY; for (V = 0; V<Graph->Nv; V++) { if (dist[V] != 0 && dist[V]<MinDist) { MinDist = dist[V]; MinV = V; } } if (MinDist<INFINITY) return MinV; else return -1; } void Prim(MGraph Graph, LGraph MST) { WeightType dist[MaxVertexNum], TotalWeight; Vertex parent[MaxVertexNum], V, W; int VCount; Edge E; //初始化,默认初始化定点下标为0 for (V = 0; V<Graph->Nv; V++) { dist[V] = Graph->G[0][V]; parent[V] = 0; } TotalWeight = 0; VCount = 0; //创建包含所有顶点但没有边的图,用邻接表表示 MST = CreateLGraph(Graph->Nv); E = (Edge)malloc(sizeof(struct ENode)); //将初始点0收录到MST dist[0] = 0; VCount++; parent[0] = -1; while (1) { V = FindMinDist(Graph, dist); if (V == -1) break; //将V及其相应的边<parent[V],V>收录进MST E->V1 = parent[V]; E->V2 = V; E->Weight = dist[V]; InsertLEdge(MST, E); TotalWeight += dist[V]; dist[V] = 0; VCount++; for (W = 0; W<Graph->Nv; W++) { if (dist[W] != 0 && Graph->G[V][W]<INFINITY) //若W是v的邻接点,且没有被收录 { if (Graph->G[V][W]<dist[W]) { dist[W] = Graph->G[V][W]; parent[W] = V; } } } } if (VCount<Graph->Nv) { TotalWeight = -1; } std::cout << "最小生成树的总权值:" << TotalWeight << endl; std::cout << "输出创建好的最小生成树的邻接表表示:" << endl; for (V = 0; V<MST->vexnum; V++) { PtrToAdjVNode W; std::cout << V<< "的邻接点:"; for (W = MST->G[V].FirstEdge; W; W = W->Next) { std::cout << W->AdjV<< "," << W->Weight << " "; } std::cout << endl; } } int _tmain(int argc, _TCHAR* argv[]) { MGraph Graph; LGraph MST = NULL; Graph = BuildMGraph(); Prim(Graph, MST); return 0; }
相关文章推荐
- wma tag 批量修改[原代码-从wmfsdk中修改]
- 网站被黑后的处理方法及批量删除恶意代码
- 再谈反向链接,又学了东西
- 大家要经常更新内容啊-针对百度的原创收录速度测试
- jsp 定制标签(Custom Tag)
- DEDECMS TAG伪静态 IIS_rewrite配置方法附rewrite下载
- 个人经验总结:网站被百度“拔毛”如何恢复?
- JSP自定义分页标签TAG全过程
- 网站优化细节之服务器的选择真没见过
- jQuery实现tag便签去重效果的方法
- 3种高效的Tags标签系统数据库设计方案分享
- Javascript让DEDECMS告别手写Tag
- 详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)
- 最小生成树算法之Prim算法
- 使用C语言实现最小生成树求解的简单方法
- 最小生成树算法——Prim和Kruskal算法的实现
- Tag技术的实现思路
- The Introduction Of Input Tag
- 很难找齐的常识
- 喜讯:富士康宣布员工整体薪资水平提升30%以上