zoukankan      html  css  js  c++  java
  • 最小生成树(普里姆算法)

    <pre name="code" class="cpp"><img src="//img-blog.csdn.net/20141130210817830" alt="" />

    
    
    #include<stdio.h>
    #include<stdlib.h>
    #include <limits.h> 
    
    #define INFINITY INT_MAX
    #define MAX_VERTEX_NUM 20
    #define OK 1
    #define ERROR -1
    #define TRUE 1
    #define FALSE 0
    
    typedef enum{DG , DN, UDG, UDN} GraphKind;//{有向图,有向网,无向图,无向网}
    typedef int VRType;
    typedef char InfoType;
    typedef int VertexType;//向量类型
    typedef int Status;
    
    typedef struct ArcCell{
    
    	VRType adj;          //无权图表示0和1,有权是权值
    	InfoType *info;      //该弧的相关信息指针
    	//int visit;
    
    }ArcCell,AdjMaxtrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    
    
    typedef struct {//邻接图结构
    
    	VertexType   vexs[MAX_VERTEX_NUM];     //顶点向量
    	AdjMaxtrix   arcs;                     //邻接矩阵
    	int          vexnum;                   //当前顶点数
    	int    		 arcnum;                   //弧度数
    	GraphKind    kind;                     //图的种类标志	
    
    }MGraph;
    
    
    Status LocateVex(MGraph G,VertexType v);
    
    
    Status CreateUDN(MGraph &G)//无向网
    {
    //	int IncInfo;
    	int i,j,k;
    	int v1,v2;
    	int w;//权重
    	printf("请输入当前顶点数和弧度数,以及弧的相关信息:");
    
    	scanf("%d%d",&G.vexnum,&G.arcnum);//如果IncInfo,表示弧没有信息
    
    	printf("请依次输入顶点:
    ");
    	for(i=0;i<G.vexnum;i++)
    		scanf("%d",&G.vexs[i]); //构造顶点向量矩阵
    
    	for(i=0;i<G.vexnum;i++)//初始化邻接矩阵
    		for(j=0;j<G.vexnum;j++)
    		{
    			G.arcs[i][j].adj=0;
    			if(i==j)
    				G.arcs[i][j].adj=0;
    			else
    				G.arcs[i][j].adj=15;
    		}
    	
    	printf("请输入两个邻接点及其权重
    ");
    	for(k=0;k<G.arcnum;k++)//根据弧度数输入顶点
    	{
    		scanf("%d%d%d",&v1,&v2,&w);
    		i=LocateVex(G,v1);
    		j=LocateVex(G,v2);
    		G.arcs[i][j].adj=w;//给v1和v2赋上权重
    		G.arcs[j][i].adj=w;
    		//if(IncInfo)
    		//	scanf("%c",&(*(G.arcs[i][j].info)));
    	}	
    	return OK;
    }//CreateUDN
    
    Status LocateVex(MGraph G,VertexType v)//得到当前顶点矩阵的位置
    {
    	for(int i=0;i<G.vexnum;i++)
    		if(G.vexs[i]==v)
    			return i;
    
    	return ERROR;
    }
    
    
    Status GetVex(MGraph G,int v)//返回v的某个顶点
    {
    	if(v>=G.arcnum||v<0)
    		exit(ERROR);
    	return G.vexs[v];
    }
    
    Status FirstAdjVex(MGraph &G, VertexType v)//返回为的第一个邻接顶点的序列号
    {
    	int i=LocateVex(G,v);
    	for(int k=0;k<G.vexnum;k++)
    		if(G.arcs[i][k].adj)
    			return G.vexs[k];
    	return ERROR;
    }
    
    Status NextAdjVex(MGraph G,VertexType v,VertexType w)//返回w的的下一个邻接顶点
    {
    	int i=LocateVex(G,v);
    	int k=LocateVex(G,w);
    	for(int j=k;j<G.vexnum;j++)
    		if(G.arcs[i][j].adj==1&&j>k)
    			return G.vexs[j];
    
    	return ERROR;
    }
    
    Status InsertVex(MGraph &G,VertexType v)//在G图中新添结点
    {
    	int i;
    	if(G.vexnum==MAX_VERTEX_NUM)//矩阵存满
    		return ERROR;
    	else
    		G.vexs[G.vexnum]=v;
    	G.vexnum++;//顶点数+1
    
    	for( i=0;i<G.vexnum;i++)//将新增的行初始化
    		G.arcs[G.vexnum-1][i].adj=0;
    
    	for( i=0;i<G.vexnum;i++)//将新增的列初始化
    		G.arcs[i][G.vexnum-1].adj=0;
    
    	return OK;
    }
    
    
    void  DeleteVex(MGraph &G,VertexType v)//删除结点v,针对无向图和无向网
    {
    	int loc=LocateVex(G,v);
    	int i,j;
    
    	for(j=0;j<G.vexnum;j++)//删掉相关的弧
    			if(G.arcs[loc][j].adj==1)
    				G.arcnum--;
    
    	for(i=0;i<G.vexnum;i++)//将所在的列删除
    		for(j=loc;j<G.vexnum-1;j++)
    			G.arcs[i][j]=G.arcs[i][j+1];
    
    	for(i=loc;i<G.vexnum-1;i++)
    		for(j=0;j<G.vexnum-1;j++)
    			G.arcs[i][j]=G.arcs[i+1][j];
    		
    	for(i=loc;i<G.vexnum-1;i++)
    		G.vexs[i]=G.vexs[i+1];
    	G.vexnum--;//结点数减一
    }
    
    void InsertArc(MGraph &G,VertexType v,VertexType w)//在G图中添加<v,w>序列
    {
    	int i,j;//获取w和v在矩阵当中的位置
    	i=LocateVex(G,v);
    	j=LocateVex(G,w);
    	G.arcs[i][j].adj=1;
    	G.arcs[j][i].adj=1;//对称弧
    }
    
    void DeleteArc(MGraph &G,VertexType v,VertexType w)
    {
    	//删除弧<v,w>,若G是无向的则还需删除对称弧<w,v>
    	int i,j;
    	G.vexnum-=2;
    	G.arcnum-=1;
    	i=LocateVex(G,v);
    	j=LocateVex(G,w);
    	G.arcs[i][j].adj=0; 
    	if(G.kind==UDN||G.kind==UDG)//如果是无向图或者无向网,删除对称偶序
    		G.arcs[j][i].adj=0;
    	
    }
    
    int Visited[MAX_VERTEX_NUM];//标志数组
    
    Status Visit(VertexType v)
    {
    	printf("%d ",v);
    	return OK;
    }
    
    void DFS(MGraph G,VertexType v)
    {
    	VertexType w;
    	int i=LocateVex(G,v);
    	if(!Visited[i])
    	{
    		Visited[i]=TRUE;
    		Visit(v);
    	}
    	for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
    		if(!Visited[LocateVex(G,w)])
    			DFS(G,w);		
    }
    
    Status DFSTraverse(MGraph G,Status(*Visit)(int v))
    {
    	int i;
    	for(i=0;i<G.vexnum;i++)//初始化标志数组
    		Visited[i]=FALSE;
    
    	printf("深度优先遍历:");	
    	for(i=0;i<G.vexnum;i++)
    		if(!Visited[i])
    			DFS(G,G.vexs[i]);
    	
    		printf("
    ");
    	return OK;
    }
    
    void PrintVex(MGraph G)
    {
    	printf("邻接矩阵为:
    ");
    	for(int i=0;i<G.vexnum;i++)
    	{
    		for(int j=0;j<G.vexnum;j++)
    			printf("%d ",G.arcs[i][j].adj);
    		printf("
    ");
    	}
    }
    
    //Prim算法求最小生成树
    
    typedef struct {//作用是存储该节点的邻接点的权值
    
    	VertexType adjvex;
    	VRType     lowcost;
    }closedge[MAX_VERTEX_NUM];
    
    
    int mininum(MGraph G,VertexType v,closedge &close)
    { 
    	VRType min;//保存最小权值
    	int j,k;
    	VertexType w;
    //	w=FirstAdjVex(G,v);
    	k=LocateVex(G,v);
    //	j=LocateVex(G,w);
    //	min=G.arcs[k][j].adj;
    	
    //	for(j=0;j<G.vexnum;j++)//找到权值最小弧
    //		if(G.arcs[k][j].adj>0&&G.arcs[k][j].adj<=min)
    //			min=G.arcs[k][j].adj;
    
    	min=15;//设置最大权重
    	for(j=0;j<G.vexnum;j++)//找到权值最小的值
    		if(close[j].lowcost>0&&close[j].lowcost<=min)
    			min=close[j].lowcost;
    
    	for(j=0;j<G.vexnum;j++)
    		if(min==close[j].lowcost)
    		{
    			close[k].adjvex=G.vexs[j];
    			return j;
    		}
    
    
    //	for(j=0;j<G.vexnum;j++)
    //		if(min==G.arcs[k][j].adj)
    //		{
    //			close[k].lowcost=G.arcs[k][j].adj;
    //			close[k].adjvex=G.vexs[j];
    //			return j;
    //		}	
    	return ERROR;
    }
    
    void MiniSpanTree_Prim(MGraph &G,VertexType v)
    {
    	int i,j,k,t;
    	closedge close;
    	for(i=0;i<G.vexnum;i++)//初始化标志数组
    		Visited[i]=FALSE;
    
    	k=LocateVex(G,v);//第一个顶点标记为访问
    	Visited[k]=TRUE;
    	for(j=0;j<G.vexnum;j++)
    		if(j!=k)
    			close[j].lowcost=G.arcs[k][j].adj;
    	close[k].lowcost=0;
    
    	for(j=0;j<G.vexnum;j++)
    	{
    		t=k;
    		k=mininum(G,G.vexs[k],close);
    		if(k>=0)
    		{
    			printf("(%2d ---%2d),弧长为%2d
    ",G.vexs[t],G.vexs[k],close[k].lowcost);
    			close[k].lowcost=0;
    			for(i=0;i<G.vexnum;i++)
    				if(G.arcs[k][i].adj<=close[i].lowcost)
    					close[i].lowcost=G.arcs[k][i].adj;
    		}
    	}
    }
    
    int main()
    {
    	VertexType v;
    	MGraph G;
    	CreateUDN(G);
    	PrintVex(G);
    	printf("输入想从那一条顶点建立二叉树:");
    	scanf("%d",&v);
    	MiniSpanTree_Prim(G,v);
    
    	return OK;
    }
    <pre name="code" class="cpp"><img src="//img-blog.csdn.net/20141130210856284" alt="" />

    
    

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    解决 未能为数据库 '数据库用户名' 中的对象 '表名' 分配空间,因为文件组 'PRIMARY' 已满
    获取一个目录下文件扩展名为txt或htm或html的文件的几种方法
    由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面
    图解C#创建SqlServer MD5 加密函数
    SqlServer 日期转换 所有格式
    使用SoapHeader对WebService进行身份验证
    禁用文本框粘贴功能
    去除 以下文件中的行尾不一致,要将行尾标准化吗 的提示
    程序锁定windows系统以及调用其它系统对话框,如控制面板,重启系统
    yakuake shell
  • 原文地址:https://www.cnblogs.com/gaot/p/4833824.html
Copyright © 2011-2022 走看看