📄 graph2m.txt
字号:
//利用普里姆算法求出用邻接矩阵表示的图的最小生成树
//图的相关数据类型的定义graph2.h
//最多顶点数
const int MaxV=10;
//最大权值
const int MaxValue=99;
//定义边集数组中的元素类型
struct RCW
{int row,col;
int weight;
};
//类定义
class adjMList
{private:
int numE;//当前边数
int GA[MaxV][MaxV];//定义邻接矩阵
public:
//构造函数,初始化图的邻接矩阵与边集数组
adjMList(RCW GE[],int n,int e);
//建立无向带权图的邻接矩阵
void CreateMatrix(int n,int &e,RCW r[]);
//输出边集数组中的每条边
void OutputEdgeSet(RCW ge[],int e);
//根据图的邻接矩阵生成图的边集数组
void ChangeEdgeSet(RCW GE[],int n,int e);
//按升序排列图的边集数组
void SortEdgeSet(RCW GE[],int e);
//利用普里姆算法从顶点v0出发求出用邻接矩阵GA表
//示的图的最小生成树,最小生成树的边集存于数组CT中
void Prim(RCW CT[],int n);
//检查输入的边序号是否越界,若越界则重输
void Check(int n, int& i, int& j);
};
//图的运算的实现文件graph2.cpp
#include"graph2.h"
//构造函数,初始化图的邻接矩阵与边集数组
adjMList::adjMList(RCW GE[],int n,int e)
{int i,j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
if(i==j) GA[i][j]=0;
else GA[i][j]=MaxValue;
for(i=0;i<e;i++) GE[i].weight=0;
numE=0;
}
//输出边集数组中的每条边
void adjMList::OutputEdgeSet(RCW ge[],int e)
{int i,k=0;
cout<<"{";
for(i=0; i<=e-2; i++)
if(ge[i].weight>0){k++;
cout<<'('<<ge[i].row<<','<<ge[i].col;
cout<<','<<ge[i].weight<<") ";
if(k%5==0) cout<<endl;}
if(e>0&&ge[i].weight>0) {
cout<<'('<<ge[e-1].row<<','<<ge[e-1].col;
cout<<','<<ge[e-1].weight<<')';}
cout<<'}'<<endl;
}
//建立无向带权图的邻接矩阵
void adjMList::CreateMatrix(int n,int &e,RCW r[])
{int i,j,k=0,w;
cout<<"依次输入无向带权图的每条边的起点和终点"<<endl;
cout<<"序号及权值!直到输入权值为0的边为止!"<<endl;
do {i=r[k].row;j=r[k].col;w=r[k].weight;
//cin>>i>>j>>w;
Check(n,i,j);
if(k==e-1) break;
GA[i][j]=GA[j][i]=w;k++;
}while(1);
numE=e=k;
cout<<"邻接矩阵:\n";
for(i=0;i<n;i++)
{for(j=0;j<n;j++)
cout<<setw(4)<<GA[i][j];
cout<<endl;}
}
//检查输入的边序号是否越界,若越界则重输
void adjMList::Check(int n, int& i, int& j)
{while(1) {
if(i<0 || i>=n ||j<0 || j>=n)
cout<<"输入有误,请重输!";
else return;
cin>>i>>j;}
}
//根据图的邻接矩阵生成图的边集数组
void adjMList::ChangeEdgeSet(RCW GE[],int n,int e)
{//假定只考虑无向图的情况
int i,j,k=0;
for(i=0; i<n; i++)
for(j=i+1; j<n; j++)
if(GA[i][j]!=0 && GA[i][j]!=MaxValue)
{if(k==e) {cout<<"数组GE下标越界!\n";
exit(1);}
GE[k].row=i;
GE[k].col=j;
GE[k].weight=GA[i][j];
k++;
}
}
//按升序排列图的边集数组
void adjMList::SortEdgeSet(RCW GE[],int e)
{int i,j;
RCW x;
for(i=1; i<=e-1; i++)
{x=GE[i];
for(j=i-1; j>=0; j--)
if(x.weight<GE[j].weight) GE[j+1]=GE[j];
else break;
GE[j+1]=x;
}
}
//利用普里姆算法从顶点v0出发求出用邻接矩阵GA表示
//的图的最小生成树,最小生成树的边集存于数组CT中
void adjMList::Prim(RCW CT[],int n)
{int i,j, k, min, t, m, w;
//给CT赋初值,对应为v0依次到其余各顶点的边
for(i=0; i<n-1; i++)
{CT[i].row=0;
CT[i].col=i+1;
CT[i].weight=GA[0][i+1];}
//进行n-1次循环,每次求出最小生成树中的第k条边
for(k=1; k<n; k++)
{//从CT[k-1]~CT[n-2]中查找最短边CT[m]
min=MaxValue;
m=k-1;
for(j=k-1; j<n-1; j++)
if(CT[j].weight<min) {
min=CT[j].weight;
m=j;}
//把最短边对调到第k-1下标位置
RCW temp=CT[k-1];
CT[k-1]=CT[m];
CT[m]=temp;
//把新并入最小生成树T中的顶点序号赋给j
j=CT[k-1].col;
//修改有关边,使T中到T外的每一个顶点各保持
//一条到目前为止最短的边
for(i=k; i<n-1; i++) {
t=CT[i].col;
w=GA[j][t];
if(w<CT[i].weight) {
CT[i].weight=w;
CT[i].row=j;
}}}}
//图的相关运算的测试graph2M.cpp
#include<iostream.h>
#include<iomanip.h>
#include "graph2.cpp"
void main()
{cout<<"graph2M.cpp运行结果:\n";
RCW rcw[20]={{0,1,50},{1,0,50},{0,2,60},{2,0,60},
{1,3,65},{3,1,65},{1,4,40},{4,1,40},{2,3,52},
{3,2,52},{2,6,45},{6,2,45},{3,4,50},{4,3,50},
{3,5,30},{5,3,30},{3,6,42},{6,3,42},{4,5,70},{5,4,70}};
int n,k;//定义图的点数及边数等
cout<<"输入图的点数n=";cin>>n;
cout<<"输入图的边数k=";cin>>k;
static RCW AE[30],BE[30];//定义边集数组
adjMList A(AE,n,k);
A.CreateMatrix(n,k,rcw);
cout<<"输出边集数组中的每条边:\n";
A.ChangeEdgeSet(AE,n,k);
A.OutputEdgeSet(AE,k);
cout<<"输出按升序排列的图的边集数组:\n";
A.SortEdgeSet(AE,k);
A.OutputEdgeSet(AE,k);
A.Prim(BE,n);
cout<<"输出最小生成树的边集数组:\n";
A.OutputEdgeSet(BE,k);
cin.get();cin.get();}
graph2M.cpp运行结果:
输入图的点数n=7
输入图的边数k=20
依次输入无向带权图的每条边的起点和终点
序号及权值!直到输入权值为0的边为止!
邻接矩阵:
0 50 60 99 99 99 99
50 0 99 65 40 99 99
60 99 0 52 99 99 45
99 65 52 0 50 30 42
99 40 99 50 0 70 99
99 99 99 30 70 0 99
99 99 45 42 99 99 0
输出边集数组中的每条边:
{(0,1,50) (0,2,60) (1,3,65) (1,4,40) (2,3,52)
(2,6,45) (3,4,50) (3,5,30) (3,6,42) (4,5,70)}
输出按升序排列的图的边集数组:
{(3,5,30) (1,4,40) (3,6,42) (2,6,45) (0,1,50)
(3,4,50) (2,3,52) (0,2,60) (1,3,65) (4,5,70)}
输出最小生成树的边集数组:
{(0,1,50) (1,4,40) (4,3,50) (3,5,30) (3,6,42)
(6,2,45) }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -