最小生成树 Prim算法实现C++
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if (v != u0)
{//对于v∈V-U
adjVex[v] = u0;
net.SetTag(v, UNVISITED);
}
else
{//对于v∈U
net.SetTag(v, VISITED);
adjVex[v] = u0;
}
}
for (u = 1; u < net.GetVexNum(); u++)
{//初始化标志数组
tag[iPos] = UNVISITED;
}
Matrix = (WeightType **)new WeightType *[vexNum];//生成邻接矩阵
for (iPos = 0; iPos < vexNum; iPos++)
{//生成邻接矩阵的行
Matrix[iPos] = new WeightType[vexNum];
AdjMatrixUndirNetwork<ElemType, WeightType>::AdjMatrixUndirNetwork(ElemType es[], int vertexNum, WeightType infinit)
//操作结果:构造顶点数据为es[],顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
StatusCode GetElem(int v, ElemType &e) const;//求顶点的元素
StatusCode SetElem(int v, const ElemType &e);//设置顶点的元素值
WeightType GetInfinity() const;//返回无穷大
int GetVexNum() const;//返回顶点个数
if (net.GetTag(v) == UNVISITED &&// v∈V - U
(net.GetWeight(v, w) < net.GetWeight(v, adjVex[v]) || //边<v,w>的权值更小
net.GetWeight(v, adjVex[v]) == 0) ) //不存在边<v, adjVex[v]>
for (iPos = 0; iPos < vexNum; iPos++)
{//初始化标志数组
tag[iPos] = UNVISITED;
}
Matrix = (WeightType **)new WeightType *[vexNum];//生成邻接矩阵
ElemType *elems;//顶点数据
mutable StatusCode *tag;//指向标志数组的指针
WeightType infinity;//无穷大
//辅助函数模板:
void DestroyHelp();//销毁无向网,释放无向网占用的空间
public:
//抽象数据类型方法声明及重载编译系统默认方法声明:
AdjMatrixUndirNetwork<ElemType, WeightType> &operator =(const AdjMatrixUndirNetwork<ElemType, WeightType> ©); //重载赋值运算符
};
template <class ElemType, class WeightType>
AdjMatrixUndirNetwork(int vertexNum = DEFAULT_SIZE,
WeightType infinit = (WeightType)DEFAULT_INFINITY);
//构造顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
~AdjMatrixUndirNetwork();//析构函数模板
AdjMatrixUndirNetwork<ElemType, WeightType>::AdjMatrixUndirNetwork(int vertexNum, WeightType infinit)
//操作结果:构造顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
{
if (vertexNum < 0)throw Error("顶点个数不能为负!");//抛出异常
{//选择生成树的其余net.GetVexNum() - 1个顶点
w = MinVertex(net, adjVex);
//选择使得边<w, adjVex[w]>为连接V-U到U的具有最小权值的边
if (w == -1)
{//表示U与V-U已无边相连
return;
}
cout << "edge:(" << adjVex[w] << "," << w << ") weight:"
<<net.GetWeight(w, adjVex[w])<< endl ; //输出边及权值
net.SetTag(w, VISITED);//将w并入U
for (int v = net.FirstAdjVex(w); v >= 0 ; v = net.NextAdjVex(w, v))
{//新顶点并入U后重新选择最小边
}
for (iPos = 0; iPos < vexNum; iPos++)
{
for (int jPos = 0; jPos < vexNum; jPos++)
{//为邻接矩阵元素赋值
Matrix[iPos][jPos] = infinity;
}
}
}
template <class ElemType, class WeightType>
{
if (vertexNum < 0)throw Error("顶点个数不能为负!");//抛出异常
infinity = infinit;//无穷大
vexNum = vertexNum;//顶点数为vertexNum
edgeNum = 0;//边数为0
elems = new ElemType[vexNum];//生成顶点数据标数组
void Display(const AdjMatrixUndirNetwork<ElemType, WeightType> &g, bool showVexElem);//显示邻接矩阵无向网
//无向网的邻接矩阵类的实现部分
template <class ElemType, class WeightType>
int GetEdgeNum() const;//返回边数个数
int FirstAdjVex(int v) const;//返回顶点v的第一个邻接点
int NextAdjVex(int v1, int v2) const;//返回顶点v1的相对于v2的下一个邻接点
void InsertEdge(int v1, int v2, WeightType w);//插入顶点为v1和v2,权为w的边
//无向网的邻接矩阵类模板
template <class ElemType, class WeightType>
class AdjMatrixUndirNetwork
{
protected:
//邻接矩阵的数据成员:
int vexNum, edgeNum;//顶点个数和边数
WeightType **Matrix;//邻接矩阵
infinity = infinit;//无穷大
vexNum = vertexNum;//顶点数为vertexNum
edgeNum = 0;//边数为0
elems = new ElemType[vexNum];//生成顶点数据标数组
int iPos;//临时变量
tag = new StatusCode[vexNum];//生成标志数组
最小生成树Prim算法实现的c ++语言,使用邻接矩阵存储边信息。共三个文件。
第一个
#ifndef __PRIM_H__
#define __PRIM_H__
template <class ElemType, class WeightType>
int MinVertex(const AdjMatrixUndiHale Waihona Puke BaiduNetwork<ElemType, WeightType> &net, int *adjVex)
//操作结果:返回w,使得边<w, adjVex[w]>为连接V-U到U的具有最小权值的边
{
int w = -1;//初始化最小顶点
int v;//临时顶点
for (v = 0; v < net.GetVexNum(); v++)
{//查找第一个满足条件的V - U中顶点v
if (net.GetTag(v) == UNVISITED//表示v为V - U中的顶点
&& net.GetWeight(v, adjVex[v]) > 0)//存在从v到U的边(v, adjVex[v])
{
w = v;
break;
}
}
for (v++; v < net.GetVexNum(); v++)//查找连接V-U到U的具有最小权值的边<w, adjVex[w]>
if (net.GetTag(v) == UNVISITED && net.GetWeight(v, adjVex[v]) >0 &&
void DeleteEdge(int v1, int v2);//删除顶点为v1和v2的边
WeightType GetWeight(int v1, int v2) const;//返回顶点为v1和v2的边的权值
void SetWeight(int v1, int v2, WeightType w);//设置顶点为v1和v2的边的权值
AdjMatrixUndirNetwork(ElemType es[], int vertexNum = DEFAULT_SIZE,
WeightType infinit = (WeightType)DEFAULT_INFINITY);
//构造顶点数据为es[],顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
{// <v, w>为新的最小边
adjVex[v] = w;
}
}
}
delete []adjVex;//释放存储空间
}
#endif
第二个
#ifndef __ADJ_MATRIX_UNDIR_GRAPH_H__
#define __ADJ_MATRIX_UNDIR_GRAPH_H__
#include "utility.h"//实用程序软件包
//初始条件:存在网net,u0为g的一个顶点
//操作结果:用Prim算法从u0出发构造网g的最小代价生成树
{
if (u0 < 0 || u0 >= net.GetVexNum())throw Error("u0不合法1!");//抛出异常
int *adjVex;//如果v∈V-U,net.GetWeight(v, adjVex[v])>0
//表示(v, adjVex[v])是v到U具有最小权值边的邻接点
int u, v, w;//表示顶点的临时变量
adjVex = new int[net.GetVexNum()];//分配存储空间
for (v = 0; v < net.GetVexNum(); v++)
{//初始化辅助数组adjVex,并对顶点作标志,此时U = {v0}
net.GetWeight(v, adjVex[v]) < net.GetWeight(w, adjVex[w]))
w = v;
return w;
}
template <class ElemType, class WeightType>
void MiniSpanTreePrim(const AdjMatrixUndirNetwork<ElemType, WeightType> &net, int u0)
StatusCode GetTag(int v) const;//返回顶点v的标志
void SetTag(int v, StatusCode val) const;//设置顶点v的标志为val
AdjMatrixUndirNetwork(const AdjMatrixUndirNetwork<ElemType, WeightType> ©);//复制构造函数模样
int iPos;//临时变量
for (iPos = 0; iPos < vexNum; iPos++)
{//初始化标志数组
elems[iPos] = es[iPos];
}
tag = new StatusCode[vexNum];//生成标志数组
for (iPos = 0; iPos < vexNum; iPos++)
{//对于v∈V-U
adjVex[v] = u0;
net.SetTag(v, UNVISITED);
}
else
{//对于v∈U
net.SetTag(v, VISITED);
adjVex[v] = u0;
}
}
for (u = 1; u < net.GetVexNum(); u++)
{//初始化标志数组
tag[iPos] = UNVISITED;
}
Matrix = (WeightType **)new WeightType *[vexNum];//生成邻接矩阵
for (iPos = 0; iPos < vexNum; iPos++)
{//生成邻接矩阵的行
Matrix[iPos] = new WeightType[vexNum];
AdjMatrixUndirNetwork<ElemType, WeightType>::AdjMatrixUndirNetwork(ElemType es[], int vertexNum, WeightType infinit)
//操作结果:构造顶点数据为es[],顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
StatusCode GetElem(int v, ElemType &e) const;//求顶点的元素
StatusCode SetElem(int v, const ElemType &e);//设置顶点的元素值
WeightType GetInfinity() const;//返回无穷大
int GetVexNum() const;//返回顶点个数
if (net.GetTag(v) == UNVISITED &&// v∈V - U
(net.GetWeight(v, w) < net.GetWeight(v, adjVex[v]) || //边<v,w>的权值更小
net.GetWeight(v, adjVex[v]) == 0) ) //不存在边<v, adjVex[v]>
for (iPos = 0; iPos < vexNum; iPos++)
{//初始化标志数组
tag[iPos] = UNVISITED;
}
Matrix = (WeightType **)new WeightType *[vexNum];//生成邻接矩阵
ElemType *elems;//顶点数据
mutable StatusCode *tag;//指向标志数组的指针
WeightType infinity;//无穷大
//辅助函数模板:
void DestroyHelp();//销毁无向网,释放无向网占用的空间
public:
//抽象数据类型方法声明及重载编译系统默认方法声明:
AdjMatrixUndirNetwork<ElemType, WeightType> &operator =(const AdjMatrixUndirNetwork<ElemType, WeightType> ©); //重载赋值运算符
};
template <class ElemType, class WeightType>
AdjMatrixUndirNetwork(int vertexNum = DEFAULT_SIZE,
WeightType infinit = (WeightType)DEFAULT_INFINITY);
//构造顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
~AdjMatrixUndirNetwork();//析构函数模板
AdjMatrixUndirNetwork<ElemType, WeightType>::AdjMatrixUndirNetwork(int vertexNum, WeightType infinit)
//操作结果:构造顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
{
if (vertexNum < 0)throw Error("顶点个数不能为负!");//抛出异常
{//选择生成树的其余net.GetVexNum() - 1个顶点
w = MinVertex(net, adjVex);
//选择使得边<w, adjVex[w]>为连接V-U到U的具有最小权值的边
if (w == -1)
{//表示U与V-U已无边相连
return;
}
cout << "edge:(" << adjVex[w] << "," << w << ") weight:"
<<net.GetWeight(w, adjVex[w])<< endl ; //输出边及权值
net.SetTag(w, VISITED);//将w并入U
for (int v = net.FirstAdjVex(w); v >= 0 ; v = net.NextAdjVex(w, v))
{//新顶点并入U后重新选择最小边
}
for (iPos = 0; iPos < vexNum; iPos++)
{
for (int jPos = 0; jPos < vexNum; jPos++)
{//为邻接矩阵元素赋值
Matrix[iPos][jPos] = infinity;
}
}
}
template <class ElemType, class WeightType>
{
if (vertexNum < 0)throw Error("顶点个数不能为负!");//抛出异常
infinity = infinit;//无穷大
vexNum = vertexNum;//顶点数为vertexNum
edgeNum = 0;//边数为0
elems = new ElemType[vexNum];//生成顶点数据标数组
void Display(const AdjMatrixUndirNetwork<ElemType, WeightType> &g, bool showVexElem);//显示邻接矩阵无向网
//无向网的邻接矩阵类的实现部分
template <class ElemType, class WeightType>
int GetEdgeNum() const;//返回边数个数
int FirstAdjVex(int v) const;//返回顶点v的第一个邻接点
int NextAdjVex(int v1, int v2) const;//返回顶点v1的相对于v2的下一个邻接点
void InsertEdge(int v1, int v2, WeightType w);//插入顶点为v1和v2,权为w的边
//无向网的邻接矩阵类模板
template <class ElemType, class WeightType>
class AdjMatrixUndirNetwork
{
protected:
//邻接矩阵的数据成员:
int vexNum, edgeNum;//顶点个数和边数
WeightType **Matrix;//邻接矩阵
infinity = infinit;//无穷大
vexNum = vertexNum;//顶点数为vertexNum
edgeNum = 0;//边数为0
elems = new ElemType[vexNum];//生成顶点数据标数组
int iPos;//临时变量
tag = new StatusCode[vexNum];//生成标志数组
最小生成树Prim算法实现的c ++语言,使用邻接矩阵存储边信息。共三个文件。
第一个
#ifndef __PRIM_H__
#define __PRIM_H__
template <class ElemType, class WeightType>
int MinVertex(const AdjMatrixUndiHale Waihona Puke BaiduNetwork<ElemType, WeightType> &net, int *adjVex)
//操作结果:返回w,使得边<w, adjVex[w]>为连接V-U到U的具有最小权值的边
{
int w = -1;//初始化最小顶点
int v;//临时顶点
for (v = 0; v < net.GetVexNum(); v++)
{//查找第一个满足条件的V - U中顶点v
if (net.GetTag(v) == UNVISITED//表示v为V - U中的顶点
&& net.GetWeight(v, adjVex[v]) > 0)//存在从v到U的边(v, adjVex[v])
{
w = v;
break;
}
}
for (v++; v < net.GetVexNum(); v++)//查找连接V-U到U的具有最小权值的边<w, adjVex[w]>
if (net.GetTag(v) == UNVISITED && net.GetWeight(v, adjVex[v]) >0 &&
void DeleteEdge(int v1, int v2);//删除顶点为v1和v2的边
WeightType GetWeight(int v1, int v2) const;//返回顶点为v1和v2的边的权值
void SetWeight(int v1, int v2, WeightType w);//设置顶点为v1和v2的边的权值
AdjMatrixUndirNetwork(ElemType es[], int vertexNum = DEFAULT_SIZE,
WeightType infinit = (WeightType)DEFAULT_INFINITY);
//构造顶点数据为es[],顶点个数为vertexNum,infinit表示无穷大,边数为0的无向网
{// <v, w>为新的最小边
adjVex[v] = w;
}
}
}
delete []adjVex;//释放存储空间
}
#endif
第二个
#ifndef __ADJ_MATRIX_UNDIR_GRAPH_H__
#define __ADJ_MATRIX_UNDIR_GRAPH_H__
#include "utility.h"//实用程序软件包
//初始条件:存在网net,u0为g的一个顶点
//操作结果:用Prim算法从u0出发构造网g的最小代价生成树
{
if (u0 < 0 || u0 >= net.GetVexNum())throw Error("u0不合法1!");//抛出异常
int *adjVex;//如果v∈V-U,net.GetWeight(v, adjVex[v])>0
//表示(v, adjVex[v])是v到U具有最小权值边的邻接点
int u, v, w;//表示顶点的临时变量
adjVex = new int[net.GetVexNum()];//分配存储空间
for (v = 0; v < net.GetVexNum(); v++)
{//初始化辅助数组adjVex,并对顶点作标志,此时U = {v0}
net.GetWeight(v, adjVex[v]) < net.GetWeight(w, adjVex[w]))
w = v;
return w;
}
template <class ElemType, class WeightType>
void MiniSpanTreePrim(const AdjMatrixUndirNetwork<ElemType, WeightType> &net, int u0)
StatusCode GetTag(int v) const;//返回顶点v的标志
void SetTag(int v, StatusCode val) const;//设置顶点v的标志为val
AdjMatrixUndirNetwork(const AdjMatrixUndirNetwork<ElemType, WeightType> ©);//复制构造函数模样
int iPos;//临时变量
for (iPos = 0; iPos < vexNum; iPos++)
{//初始化标志数组
elems[iPos] = es[iPos];
}
tag = new StatusCode[vexNum];//生成标志数组
for (iPos = 0; iPos < vexNum; iPos++)