数据结构--最小生成树(Prim算法)
来源:互联网 发布:绝对领域 知乎 编辑:程序博客网 时间:2024/04/20 03:42
头文件 Graph.h//以数组形式构造图#pragma once#include <iostream>#include <queue>using namespace std;#define INFINITY INT_MAX#define NAX_VERTEX_NUM 20#define VRtype int//#define InfoType char*#define VertexType char*#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2#define INFEASIBLE -1bool visited[NAX_VERTEX_NUM];void(*VisitFunc)(VertexType);typedef enum{ DG,DN,UDG,UDN//有向图,有向网,无向图,无向网}GraphKind;typedef struct ArcCell{ VRtype adj;//无权图,用0或1;带权图,即权值 //InfoType *info; }ArcCell, AdjMatrix[NAX_VERTEX_NUM][NAX_VERTEX_NUM];typedef struct //定义图的结构{ VertexType vexs[NAX_VERTEX_NUM];//顶点向量 AdjMatrix arcs; //邻接矩阵 int vexnum,arcnum; //定点数,边(弧)数 GraphKind kind; //图的种类标记}MGraph;int CreateDG(MGraph &G);//构造有向图int CreateDN(MGraph &G);//构造有向网int CreateUDG(MGraph &G);//构造无向图int CreateUDN(MGraph &G);//构造无向网int CreateGraph(MGraph &G)//采用数组(邻接矩阵)表示法,构造图G{ int n; cout<<"创建有向图(0),有向网(1),无向图(2),无向网(3)"<<endl; cin>>n; switch(n) { case DG: G.kind = DG; return CreateDG(G);//有向图 case DN: G.kind = DN; return CreateDN(G);//有向网 case UDG: G.kind = UDG; return CreateUDG(G);//无向图 case UDN: G.kind = UDN; return CreateUDN(G);//无向网 default: return ERROR; }}int LocateVex(MGraph G, VertexType V)//顶点V在图中的位置{ int i; for(i=0; i<G.vexnum; i++) { if(strcmp(G.vexs[i],V) == 0) return i; } return -1;//不存在,返回-1}int CreateUDG(MGraph &G)//构造无向图{ cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = 0; //G.arcs[i][j].info = NULL; } } char *v1, *v2; v1 = (char*)malloc(sizeof(char)); v2 = (char*)malloc(sizeof(char)); for(k=0; k<G.arcnum; k++)//构造邻接矩阵 { cout<<"输入相连的边(v1,v2):"; cin>>v1>>v2; i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = 1;//权值 G.arcs[j][i] = G.arcs[i][j];//无向图中,邻接矩阵对称 } G.kind = UDG;//无向图 return OK;}int CreateDG(MGraph &G)//构造有向图{ cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = 0; //G.arcs[i][j].info = NULL; } } char *v1, *v2; v1 = (char*)malloc(sizeof(char)); v2 = (char*)malloc(sizeof(char)); for(k=0; k<G.arcnum; k++)//构造邻接矩阵 { cout<<"输入连接的边(v1,v2):"; cin>>v1>>v2; i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = 1;//权值 } G.kind = DG;//有向图 return OK;}int CreateUDN(MGraph &G)//采用数组(邻接矩阵)表示法,构造无向网{ //int IncInfo; cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = INFINITY; //G.arcs[i][j].info = NULL; } } char *v1, *v2; v1 = (char*)malloc(sizeof(char)); v2 = (char*)malloc(sizeof(char)); int w; for(k=0; k<G.arcnum; k++)//构造邻接矩阵 { cout<<"输入边及其权重(v1,v2,w):"; cin>>v1>>v2>>w; i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = w;//权值 G.arcs[j][i] = G.arcs[i][j];//无向网中,邻接矩阵对称 } G.kind = UDN;//无向网 return OK;}int CreateDN(MGraph &G)//采用数组(邻接矩阵)表示法,构造有向网{ //int IncInfo; cout<<"输入顶点数,边数:"<<endl; cin>>G.vexnum>>G.arcnum; int i,j,k; for(i=0; i<G.vexnum; i++)//构造顶点向量 { cout<<"输入第"<<i+1<<"个顶点的名称:"; G.vexs[i] = (VertexType)malloc( sizeof(char) ); cin>>G.vexs[i]; } for(i=0; i<G.vexnum; i++)//初始化领接矩阵 { for(j=0; j<G.vexnum; j++) { G.arcs[i][j].adj = INFINITY; //G.arcs[i][j].info = NULL; } } char *v1, *v2; v1 = (char*)malloc(sizeof(char)); v2 = (char*)malloc(sizeof(char)); int w; for(k=0; k<G.arcnum; k++)//构造邻接矩阵 { cout<<"输入边及其权重(v1,v2,w):"; cin>>v1>>v2>>w; i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置 j = LocateVex(G,v2); G.arcs[i][j].adj = w;//权值 } G.kind = DN;//有向网 return OK;}VertexType GetVex(MGraph G, int v)//返回图中第V个顶点{ if(v<1 || v>G.vexnum) return NULL; else return G.vexs[v-1];//顶点数组以标号0开始}int PutVex(MGraph &G, VertexType v, VertexType value)//修改图中顶点v的名称为value{ int i = LocateVex(G,v); if(i<0) return ERROR; else strcpy(G.vexs[i],value); return OK;}VertexType FirstAdjVex(MGraph G, VertexType v)//返回顶点V的第一个邻接点{ int i,j,k; k = LocateVex(G,v);//定位顶点v在图中的位置 if(k<0) return NULL; if(G.kind % 2 == 1)//网 j = INFINITY; else j = 0;//图 for(i=0; i<G.vexnum; i++) { if(G.arcs[k][i].adj != j)//邻接矩阵中该行第一个不为j的分量所在的列号 return GetVex(G,i+1); } return NULL;}VertexType NextAdjVex(MGraph G, VertexType v, VertexType w)//返回顶点V的(相对于w)下一个邻接点{ int i,j,k,p; i = LocateVex(G,v); j = LocateVex(G,w); if(i<0 || j<0) return NULL; if(G.kind % 2 == 1)//网 k = INFINITY; else k = 0;//图 for(p=j+1; p<G.vexnum; p++) { if(G.arcs[i][p].adj != k) return GetVex(G,p+1); } return NULL;}void InsertVex(MGraph &G, VertexType v)//插入顶点{ int j,i; if(G.kind % 2 == 1) j = INFINITY;//网 else j = 0;//图 G.vexs[G.vexnum] = (VertexType)malloc(sizeof(VertexType)); strcpy(G.vexs[G.vexnum],v); for(i=0; i<=G.vexnum; i++) G.arcs[G.vexnum][i].adj = G.arcs[i][G.vexnum].adj = j;//初始化权值 G.vexnum++;}int DeleteVex(MGraph &G, VertexType v)//删除顶点{ int i,j,k,p; k = LocateVex(G,v); if(k<0) return ERROR; if(G.kind % 2 == 1) j = INFINITY;//网 else j = 0;//图 for(i=0; i<G.vexnum; i++)//入弧(出度) if(G.arcs[k][i].adj != j) G.arcnum--; if(G.kind < 2)//有向 for(i=0; i<G.vexnum; i++) if(G.arcs[i][k].adj != j) G.arcnum--; for(i=k+1; i<G.vexnum; i++)//顶点向量第k个之后的都往前移 strcpy(G.vexs[i-1],G.vexs[i]); //free(G.vexs[i-1]); G.vexs[i-1] = NULL; for(i=0; i<G.vexnum; i++)//邻接矩阵中每行从第k列之后的都往前移 { for(p=k+1; p<G.vexnum; p++) G.arcs[i][p-1] = G.arcs[i][p]; G.arcs[i][p-1].adj = j; } G.arcs[i-1][p-1].adj = j; for(i=k+1; i<G.vexnum; i++)//邻接矩阵中每列从第k行之后的都往上移 { for(p=0; p<G.vexnum-1; p++) { G.arcs[i-1][p] = G.arcs[i][p]; if(i == G.vexnum-1) G.arcs[i][p].adj = j; } } G.vexnum--; return OK;}int InsertArc(MGraph &G, VertexType v, VertexType w)//插入一条边或弧{ int i,j,weight; i = LocateVex(G,v);//尾 j = LocateVex(G,w);//头 if(i<0 || j<0) return ERROR; G.arcnum++; if(G.kind % 2 == 1) { cout<<"输入权值:"; cin>>weight; } else weight = 1; if(G.kind < 2)//有向 G.arcs[i][j].adj = weight; else//无向 G.arcs[j][i].adj= G.arcs[i][j].adj=weight; return OK;}int DeleteArc(MGraph &G, VertexType v, VertexType w)//删除一条边{ int i,j,weight; i = LocateVex(G,v);//尾 j = LocateVex(G,w);//头 if(i<0 || j<0) return ERROR; G.arcnum--; if(G.kind % 2 == 1)//网 weight = INFINITY; else//图 weight = 1; if(G.kind < 2)//有向 G.arcs[i][j].adj = weight; else G.arcs[i][j].adj = G.arcs[j][i].adj = weight; return OK;}void Display(MGraph G)//输出邻接矩阵{ int i,j; for(i=0; i<G.vexnum; i++) { for(j=0; j<G.vexnum; j++) { cout<<"("<<G.vexs[i]<<"->"<<G.vexs[j]<<","; if(G.arcs[i][j].adj == INFINITY) cout<<"oo"; else cout<<G.arcs[i][j].adj; cout<<")"<<" "; } cout<<endl; }}void Visit(VertexType e){ cout<<e;}void DFS(MGraph G, int v){ visited[v] = TRUE;//访问第v个结点 VisitFunc(G.vexs[v]); VertexType w; for(w=FirstAdjVex(G,G.vexs[v]); w!=NULL; w=NextAdjVex(G,G.vexs[v],w) )//对第v个顶点尚未访问的邻接结点w递归调用DFS { if(!visited[LocateVex(G,w)]) DFS(G,LocateVex(G,w)); }}void DFSTraverse(MGraph G, void(*Visit)(VertexType))//深度优先遍历{ int v; VisitFunc = Visit; for(v=0; v<G.vexnum; v++) visited[v] = FALSE;//访问标志数组 for(v=0; v<G.vexnum; v++) if(!visited[v])//对尚未访问的顶点调用DFS DFS(G,v); cout<<endl;}void BFSTraverse(MGraph G, void(*Visit)(VertexType))//广度优先搜索算法{ int i,u; VertexType w; for(i=0; i<G.vexnum; i++)//访问标记数组初始化 visited[i] = FALSE; queue<int> Q; //置空的辅助队列 for(i=0; i<G.vexnum; i++) { if(!visited[i]) { visited[i] = TRUE; Visit(G.vexs[i]); Q.push(i); while(!Q.empty()) { u = Q.front();//对头元素出队并置为u Q.pop(); for(w=FirstAdjVex(G,G.vexs[u]); w!=NULL; w=NextAdjVex(G,G.vexs[u],w)) { //w为u的尚未访问的邻接顶点 if(!visited[LocateVex(G,w)]) { visited[LocateVex(G,w)] = TRUE; Visit(w); Q.push(LocateVex(G,w)); } } } } } cout<<endl;}// Minimum Cost Spanning Tree.cpp : Defines the entry point for the console application./*-----CODE FOR FUN----------------------CREATED BY Dream_Whui-------------2015-2-12--------------------*/#include "stdafx.h"#include "Graph.h"typedef struct //记录从顶点集U到V-U的代价最小的边的辅助数组定义{ VertexType adjvex; //起始顶点的名称 VRtype lowcost; //边的权值}closedge[NAX_VERTEX_NUM]; //例 closedge[0]:{adjvex = v2, lowcost = n} 表示顶点v2到顶点v1,边的权重为n //closedge[1]...closedge[NAX_VERTEX_NUM]类同int minimun(MGraph G, closedge closed_array){ int i; int min = INFINITY; int flag; for(i=0; i<G.vexnum; i++) { if(closed_array[i].lowcost < min && closed_array[i].lowcost > 0) { min = closed_array[i].lowcost; flag = i; } } return flag;}void MiniSpanTree_PRIM(MGraph G, VertexType u)//用普里姆算法计算从第u个顶点出发构造网G的最小生成树T,输出T的各条边{ int k; k = LocateVex(G,u);//顶点u在网中的位置 int i,j; closedge closed_array;//定义辅助数组 for(j=0; j<G.vexnum; j++) { closed_array[j].adjvex = (VertexType)malloc(sizeof(char));//分配边的起始顶点名称的空间 if(j!=k) { closed_array[j].adjvex = u;//起始顶点名称u closed_array[j].lowcost = G.arcs[k][j].adj;//边的权值 } } closed_array[k].lowcost = 0; //初始,U={u} cout<<"最小生成树"<<endl; for(i=1; i<G.vexnum; i++) { k = minimun(G,closed_array); //在辅助数组中找到权值最小的那条边,且MIN{closed_array[vi].lowcost && closed_array[vi].lowcost>0} cout<<closed_array[k].adjvex<<"->"<<G.vexs[k]<<endl;//输出树的边 closed_array[k].lowcost = 0; //第k个顶点并入U集 for(j=0; j<G.vexnum; j++) if(G.arcs[k][j].adj < closed_array[j].lowcost)//新顶点并入后重新 选择最小边 { closed_array[j].adjvex = G.vexs[k]; closed_array[j].lowcost = G.arcs[k][j].adj; } }}int main(int argc, char* argv[]){ MGraph G; CreateGraph(G); MiniSpanTree_PRIM(G,G.vexs[0]); return 0;}
0 0
- 数据结构--最小生成树(Prim算法)
- 数据结构:最小生成树(Prim算法)
- [数据结构]普里姆(Prim)算法生成最小生成树
- 数据结构:最小生成树--Prim算法
- 数据结构之最小生成树prim算法
- 数据结构-最小生成树-Prim算法
- 数据结构 最小生成树 Prim算法
- 数据结构:最小生成树--Prim算法
- 数据结构5-最小生成树Prim算法
- 数据结构--图--最小生成树(Prim算法)
- 数据结构(C实现)------- 最小生成树之Prim算法
- 数据结构与算法系列----最小生成树(Prim算法&Kruskal算法)
- 《大话数据结构》最小生成树——Prim算法
- 数据结构——邻接矩阵的最小生成树Prim算法
- 数据结构之图---最小生成树Prim算法---C++实现
- 数据结构--图的最小生成树Prim算法
- C语言-数据结构-prim算法求最小生成树
- 最小生成树(prim算法)
- 数据结构---图的连通性
- Android反调试之 AntiEmulator 检测安卓模拟器
- cuda的优化技术
- POJ 2823 Sliding Window(单调队列)
- NYOJ--21(搜索)-题目-----------------------------三个水杯
- 数据结构--最小生成树(Prim算法)
- 我的maven项目常用配置
- 【学习心得】linux下多客户端批量操作脚本(含expect交互)
- 数据结构---图(邻接表)
- 显示缓存内容
- enum和int的相互转换
- 数据结构---图(求关节点)
- matlab新手入门篇
- SRTM DEM 下载网址