普里姆(Prim)算法

  1 /*
  2 普里姆算法的主要思想:
  3     利用二维数组把权值放入,然后找在当前顶点的最小权值,然后走过的路用一个数组来记录
  4 */
  5 # include <stdio.h>
  6
  7 typedef char VertexType;//定义顶点类型
  8 typedef int EdgeType;//定义边上的权值类型
  9 # define MAX_VERTEX 100//最大顶点个数
 10 # define INFINITY 65535//用65535代表无穷大
 11
 12 typedef struct
 13 {//邻接矩阵存储结构
 14     VertexType vexs[MAX_VERTEX];//顶点表
 15     EdgeType arc[MAX_VERTEX][MAX_VERTEX];//邻接矩阵
 16     int numVertexs, numEdges;//图中当前的顶点数和边数
 17
 18 }MGraph;
 19
 20 void CreateMGraph(MGraph *G)
 21 {
 22     int i, j;
 23     G->numEdges=15;
 24     G->numVertexs=9;
 25
 26     for (i = 0; i < G->numVertexs; i++)
 27     {
 28         for ( j = 0; j < G->numVertexs; j++)
 29         {
 30             if (i==j)
 31                 G->arc[i][j]=0;
 32             else
 33                 G->arc[i][j] = G->arc[j][i] = INFINITY;
 34         }
 35     }
 36
 37     G->arc[0][1]=10;
 38     G->arc[0][5]=11;
 39     G->arc[1][2]=18;
 40     G->arc[1][8]=12;
 41     G->arc[1][6]=16;
 42     G->arc[2][8]=8;
 43     G->arc[2][3]=22;
 44     G->arc[3][8]=21;
 45     G->arc[3][6]=24;
 46     G->arc[3][7]=16;
 47     G->arc[3][4]=20;
 48     G->arc[4][7]=7;
 49     G->arc[4][5]=26;
 50     G->arc[5][6]=17;
 51     G->arc[6][7]=19;
 52
 53     for(i = 0; i < G->numVertexs; i++)
 54     {
 55         for(j = i; j < G->numVertexs; j++)
 56         {
 57             G->arc[j][i] =G->arc[i][j];
 58         }
 59     }
 60
 61 }
 62
 63 void MinSpanTree_Peim (MGraph &G)
 64 {//普里姆算法,最小生成树
 65     int min, i, j, k;
 66     int add=0;
 67     int adjvex[MAX_VERTEX];
 68     int lowcost[MAX_VERTEX];
 69     lowcost[0] = 0;
 70     adjvex[0] = 0;
 71
 72     for (i=1; i<G.numVertexs; i++)
 73     {//若是从v0顶点开始查找,从顶点v0的矩阵全部赋值到lowcost数组中,adjvex数组全部为0;
 74         lowcost[i] = G.arc[0][i];//二维数组存放的权值
 75         adjvex[i] = 0;//所有都为0
 76     }
 77
 78     for (i=1; i<G.numVertexs; i++)
 79     {//最小生成树
 80         min = INFINITY;//无穷大
 81         j=1;
 82         k=0;
 83
 84         while (j < G.numVertexs)
 85         {//查找lowcost数组中最小的值,把最小的值赋给min,且最小值的下表赋给k
 86             if (lowcost[j]!=0 && lowcost[j]<min)
 87             {
 88                 min = lowcost[j];//存放最小的权值
 89                 k = j;//把存放最小权值的顶点下标
 90             }
 91             j++;
 92         }
 93         printf ("(%d——%d)\n", adjvex[k], k);
 94         add = add + G.arc[adjvex[k]][k];
 95         /*因为52~56行已经把adjvex数组全部赋值为0,所以一开始打印出来的就是0,后来打印出来的就是以上一个在lowcost
 96         数组中最小值的下表(下表对应的顶点),顶点的矩阵中比当前lowcost数组中的值还要小的值的下标,和lowcost数组中最小值的下标*/
 97         lowcost[k] = 0;
 98         //若刚才存放最小权值的顶点是1(k=1),则下面就for循环就从发1的二位数组继续寻找最小生成树
 99         for (j=1; j<G.numVertexs; j++)
100         {//以在lowcost数组中最小值的下表作为二位数组的第一个下标与当前lowcos数组中的值进行比较。
101          //查找最小值
102             if (lowcost[j]!=0 && G.arc[k][j]<lowcost[j])//t
103             {
104                 lowcost[j] = G.arc[k][j];//0
105                 adjvex[j] = k;
106             }
107         }
108     }
109     printf ("%d\n", add);
110
111     return;
112 }
113
114 int main (void)
115 {
116     MGraph G;
117     CreateMGraph (&G);
118     MinSpanTree_Peim (G);
119
120     return 0;
121 }
122
123 /*
124                                         在vc++6.0运行结果:
125 请输入顶点数和边数:9 15
126 请输入第1个顶点信息:v0
127 请输入第2个顶点信息:v1
128 请输入第3个顶点信息:v2
129 请输入第4个顶点信息:v3
130 请输入第5个顶点信息:v4
131 请输入第6个顶点信息:v5
132 请输入第7个顶点信息:v6
133 请输入第8个顶点信息:v7
134 请输入第9个顶点信息:v8
135 请输入边(vi,vj)上的下表i,下表j和权w:0 1 10
136 请输入边(vi,vj)上的下表i,下表j和权w:0 5 11
137 请输入边(vi,vj)上的下表i,下表j和权w:1 6 16
138 请输入边(vi,vj)上的下表i,下表j和权w:1 2 18
139 请输入边(vi,vj)上的下表i,下表j和权w:1 8 12
140 请输入边(vi,vj)上的下表i,下表j和权w:2 8 8
141 请输入边(vi,vj)上的下表i,下表j和权w:2 3 22
142 请输入边(vi,vj)上的下表i,下表j和权w:8 3 21
143 请输入边(vi,vj)上的下表i,下表j和权w:6 5 17
144 请输入边(vi,vj)上的下表i,下表j和权w:6 3 24
145 请输入边(vi,vj)上的下表i,下表j和权w:6 7 19
146 请输入边(vi,vj)上的下表i,下表j和权w:3 4 20
147 请输入边(vi,vj)上的下表i,下表j和权w:3 7 16
148 请输入边(vi,vj)上的下表i,下表j和权w:4 7 7
149 请输入边(vi,vj)上的下表i,下表j和权w:4 5 26
150 (0——1)
151 (0——5)
152 (1——8)
153 (8——2)
154 (1——6)
155 (6——7)
156 (7——4)
157 (7——3)
158 Press any key to continue
159
160 */
时间: 2024-10-25 18:56:35

普里姆(Prim)算法的相关文章

普里姆Prim算法 - 图解最小生成树

我们在图的定义中说过,带有权值的图就是网结构.一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边.所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小.综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree). 找连通图的最小生成树,经典的有两种算法,普里姆算法和克鲁斯卡尔算法,这里介绍普里姆算法. 为了能够讲明白这个算法,我们先构造网图的邻接矩阵,

图的最小生成树之普里姆Prim算法

源代码如下: #include<iostream> using namespace std; #define MAX_VERTEX_NUM 20 #define infinity 9 typedef int QElemType; typedef int EdgeData; typedef char VertexData; typedef struct { VertexData verlist[MAX_VERTEX_NUM]; //顶点表 EdgeData edge[MAX_VERTEX_NUM

图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 B(G).其中 T(G)是遍历图时所经过的边的集合,B(G) 是遍历图时未经过的边的集合.显然,G1(V, T) 是图 G 的极小连通子图,即子图G1 是连通图 G 的生成树. 深度优先生成森林   右边的是深度优先生成森林: 连通图的生成树不一定是唯一的,不同的遍历图的方法得到不同的生成树;从不

数据结构之---C语言实现最小生成树之prim(普里姆)算法

//最小生成树之Prim算法 //杨鑫 #include <stdio.h> #include <stdlib.h> #define n 6 #define MaxNum 10000 /*定义一个最大整数*/ /*定义邻接矩阵类型*/ typedef int adjmatrix[n + 1][n + 1]; /*0号单元没用*/ typedef struct { int fromvex, tovex; //生成树的起点和终点 int weight; //边的权重 }Edge; ty

图的最小生成树(普利姆prim算法)

什么是生成树呢? 一个连通图的生成树是指一个极小连通子图, 它含有图中的全部顶点,但只有足以构成一棵树的n-1条边. 什么是最小生成树? 在一个连通图的所有生成树中,各边的代价之和最小的那棵生成树称为该连通图的最小代价生成树(MST), 简称最小生成树. 求最小生成树有两种算法,本文讲prim算法. 简略证明 使用反证法证明 设一棵最小生成树T不包含最短边a,将a加入最小生成树T中,书中必定构成一个包含a的回路,而回路中必定有边比a大(因a为最短边),则删除比a大的边得到一棵比原先T更小的树T1

普里姆算法介绍

普里姆(Prim)算法,和克鲁斯卡尔算法一样,是用来求加权连通图的最小生成树的算法. 基本思想 对于图G而言,V是所有顶点的集合:现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G的最小生成树中的边. 从所有u?U,v?(V-U) (V-U表示出去U的所有顶点)的边中选取权值最小的边(u, v),将顶点v加入集合U中,将边(u, v)加入集合T中,如此不断重复,直到U=V为止,最小生成树构造完毕,这时集合T中包含了最小生成树中的所有边. 普里姆算法图解 以上图G4为例,

图-&gt;连通性-&gt;最小生成树(普里姆算法)

文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网.现在,我们要选择这样一个生成树,使总的耗费最少.这个问题就是构造连通网的最小代价生成树(Minimum Cost Spanning Tree: 最小生成树)的问题.一棵生成树的代价就是树上各边的代价之和. 有多种算法可以构造最小生成树,其他多数都利用的最小生成的MST(minimum

普里姆算法与修路问题

应用场景-修路问题 看一个应用场景和问题: 有胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通 各个村庄的距离用边线表示(权) ,比如 A – B 距离 5公里 问:如何修路保证各个村庄都能连通,并且总的修建公路总里程最短? 最小生成树 修路问题本质就是就是最小生成树问题, 先介绍一下最小生成树(Minimum Cost Spanning Tree),简称MST. 给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树

最小生成树 Prim(普里姆)算法和Kruskal(克鲁斯特尔)算法

Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且其所有边的权值之和亦为最小.该算法于1930年由捷克数学家沃伊捷赫·亚尔尼克(英语:Vojtěch Jarník)发现:并在1957年由美国计算机科学家罗伯特·普里姆(英语:Robert C. Prim)独立发现:1959年,艾兹格·迪科斯彻再次发现了该算法.因此,在某些场