33,317
社区成员
发帖
与我相关
我的任务
分享
#pragma once
#include<iostream>
#include<fstream>
#include"MinSpanTree.h"
#include"F:\QQPCmgr\documents\visual studio 2010\Projects\Graph\Graph_list\GraphAdjList.h" //引入基于邻接表的图
#include"F:\QQPCmgr\documents\visual studio 2010\Projects\UFSet\UFSet\UFset.h"//引入自己写的并查集
#include"F:\QQPCmgr\Documents\Visual Studio 2010\Projects\Heap\Heap\MinHeap.h"//引入自己写的最小堆
using namespace std;
template<class T, class E>
void PrimAlgorithm(GraphAdjList<T,E> &targetG,const T &beginVertex, MinSpanTree<E> &targetMSTree) //初始化算法需要的结构
{
int verticesNum = targetG.GetVerticesNum(); //获取图的顶点数目
int edgesNum = targetG.GetEdgesNum(); //获取图的边数目
int beginIndex = targetG.GetVertexPos(beginVertex); //获取起始操作顶点
MSTEdgeNode<E> tempEdgeNode; //一个生成树边结点的辅助变量
MinHeap<MSTEdgeNode<E>> mh(edgesNum); //用图的边数目初始化最小堆
bool *verticesMST = new bool[verticesNum]; //用于标志一个顶点在哪个顶点域内(如为true则在verticesMST,否则在V-verticesMST) V为图的顶点域
for(int i = 0; i < verticesNum; i++)
{
verticesMST[i] = false; //最初均在V域内
}
verticesMST[beginIndex] = true; //先把第一个操作的顶点置为true
int edgeCount = 1; //进入生成树的边数目计数器
int beginAdjIdx; //边所关联的另一个顶点索引
int nullIdx = targetG.GetNullIdx();
do
{
beginAdjIdx = targetG.GetVertexPos(targetG.GetFirstNeighbor(targetG.GetVertexValue(beginIndex))); //获取当前的第一个邻接顶点
while(beginAdjIdx != nullIdx) //第一个邻接顶点存在
{
if(verticesMST[beginAdjIdx] == false) //并且这个顶点还在吐的顶点域内
{
tempEdgeNode.head = beginIndex; //获取这个边的信息
tempEdgeNode.tail = beginAdjIdx;
tempEdgeNode.key = targetG.GetEdgeWeight(beginIndex, beginAdjIdx);
mh.Insert(tempEdgeNode); //放入最小堆中
}
beginAdjIdx = targetG.GetVertexPos(targetG.GetNextNeighbor(beginIndex, beginAdjIdx)); //再以此当前边找其他的关联边
}
//当前的关联边木有 执行下面的语句
while((mh.IsEmpty() == false) && (edgeCount < verticesNum)) //最小堆不为空,且生成树所需的边数目还不够
{
mh.RemoveMinelem(tempEdgeNode); //从最小堆中取出权值最小的边
if(verticesMST[tempEdgeNode.tail] == false) //判断该边的尾顶点是否还在图顶点域 是的话执行if语句块
{
targetMSTree.InsertEdge(tempEdgeNode); //这条边放进生成树中
beginIndex = tempEdgeNode.tail; //再将这个边的尾顶点置为当前顶点开始搜索其所关联的边
verticesMST[beginIndex] = true; //将此顶点从图顶点域中踢出,放入verticesMST中
edgeCount++; //边计数器加1
break; //一次只找一条边进入生成树,找到就跳出此while循环
}
}
}while(edgeCount < verticesNum); //最外层循环,边数目达到生成树要求,退出
}
// Win32.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
int w;
const int MAXNUM=100;
int a[MAXNUM];
int minedge[MAXNUM][MAXNUM];//括号内是两个点,此数组的值为两个点的权值
typedef struct
{
int z;
int N;
int f;
}dian;
typedef dian dianshuzu[MAXNUM];
class prim
{
public:
prim();
//创建一个带权值的图
inline void creatgraph();
inline void Prim(void);
inline void get_minedge(int v);
private:
int n;
int visited[MAXNUM];
dianshuzu a;
};
prim::prim()
{
for (int k = 0; k < MAXNUM; k++)
{
a[k].f = a[k].N = a[k].z = 0;
}
}
void prim::creatgraph()
{
int i,j,x;
cout<<"请输入顶点数"<<endl;
cin>>n;
cout<<"请输入这两个顶点是否为邻接点,如果是,输入其权值,否则请输入-1"<<endl;
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
cout<<i<<j<<endl;
cin>>x;
minedge[i][j]=x;
}
}
return;
}
void prim::Prim(void)
{
int i;
for(i=1;i<=n;i++)
visited[i]=false;//初始化将所有的点设置成未被访问
for(i=1;i<=n;i++)
{
if(visited[i]==false)
get_minedge(i);
cout<<a[w].z<<" "<<a[w].f<<" "<<a[w].N<<endl;
}
return;
}
void prim::get_minedge(int v)
{
int i,min;
min=1000;
for(w=1;w<=n;w++)
{
for(i=1;i<=n;i++)
{
if(visited[i]==false&&minedge[v][i]<min)
min=minedge[v][i];
}
a[w].z=min;//权值
a[w].f=v;//已访问的点
a[w].N=i;//未被访问的点
}
for(w=1;w<=n;w++)
{
if(a[w].z<min)
{
min=a[w].z;
visited[a[w].N]=true;//将v设置成已被访问过的点
}
}
return;
}
void main()
{
prim p;
p.creatgraph();
p.Prim();
return ;
}
帮你改了一下
class prim{
public:
prim();//这个函数没定义。。。
//创建一个带权值的图
void creatgraph(){
int i,j,x;
cout<<"请输入顶点数"<<endl;
cin>>n;
cout<<"请输入这两个顶点是否为邻接点,如果是,输入其权值,否则请输入-1"<<endl;
for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
cout<<i<<j<<endl;
cin>>x;
minedge[i][j]=x;
}
}
return;
}
void Prim(){
int i;
for(i=1;i<=n;i++)
visited[i]=false;//初始化将所有的点设置成未被访问
for(i=1;i<=n;i++){
if(visited[i]==false)
get_minedge(i);
cout<<a[w].z<<" "<<a[w].f<<" "<<a[w].N<<endl;
}
return;
}
void get_minedge(int v){
int i,min;
min=1000;
for(w=1;w<=n;w++){
for(i=1;i<=n;i++){
if(visited[i]==false&&minedge[v][i]<min)
min=minedge[v][i];
}
a[w].z=min;//权值
a[w].f=v;//已访问的点
a[w].N=i;
}//未被访问的点
for(w=1;w<=n;w++){
if(a[w].z<min){
min=a[w].z;
visited[a[w].N]=true;//将v设置成已被访问过的点
}
}
return;
}
private:
int n;
int visited[max];
dianshuzu& a;
};