// Graph_Pra.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
struct GraphNode {
string vertexName;
bool visited;
float weight;
int index;
friend bool operator < (GraphNode a, GraphNode b) {
return a.weight > b.weight;
}
};
template <class T>
class Graph {
public:
Graph(int *vertexArray, T * nameOfVertex, int numberOfVertex);
void Prim(int source); //Prim算法
void GetVexInfo(); //取顶点信息
void GerArcInfo(); //输出边信息
void SetArc(int vertextFrom, int vertextTo, int arcLength); //修改边
void DeleteVex(int vertex);
void InsertVex(int position, T name);
void DeleteArc(int vertexFrom, int vertexTo);
void InsetArc(int vertextFrom, int vertextTo, int value);
void PrintAdjacencyMatrix();
private:
int vertexNum, arcNum;
vector< vector<int> > adjacencyMatrix;
vector<GraphNode> graphNodeArray;
};
struct Arc {
int From, To;
int weight;
};
bool Rule(const Arc & p1, const Arc & p2) {
if (p1.To < p2.To)
return true;
else return false;
}
template<class T>
void Graph<T>::Prim(int source) {
int pos = 0 ;
vector<Arc> CostArc(vertexNum);
for (int i = 0; i < vertexNum; ++i) {
CostArc[i].From = source;
CostArc[i].To = i;
CostArc[i].weight = adjacencyMatrix[source][i];
}
CostArc[source].weight = 0;
vector<Arc> PrimTree;
while (PrimTree.size() != vertexNum - 1) {
pos = 0;
// for (int i = 0; i < vertexNum; ++i) cout << CostArc[i].weight << endl;
for (int i = 0; i < vertexNum; ++i) {
if ( (CostArc[pos].weight==0) ||( (CostArc[pos].weight > CostArc[i].weight)&&CostArc[i].weight!=0))
pos = i;
}
PrimTree.push_back(CostArc[pos]);
CostArc[pos].weight = 0;
for (int i = 0; i < vertexNum; ++i) {
if (adjacencyMatrix[pos][i] < CostArc[i].weight) {
CostArc[i].From = pos;
CostArc[i].weight = adjacencyMatrix[pos][i];
}
}
}
sort(PrimTree.begin(), PrimTree.end(), Rule);
for (int i = 0; i < PrimTree.size(); ++i)
cout << graphNodeArray[PrimTree[i].From].vertexName << " ---> " << graphNodeArray[PrimTree[i].To].vertexName << " ";
return;
}
template <class T>
Graph<T>::Graph(int *vertexArray, T *nameOfVertex, int numberOfVertex) {
vertexNum = numberOfVertex;
arcNum = 0;
GraphNode tempGraphNode;
for (int i = 0; i < vertexNum; i++) {
tempGraphNode.vertexName = nameOfVertex[i];
tempGraphNode.index = i;
graphNodeArray.push_back(tempGraphNode);
}
adjacencyMatrix.resize(vertexNum, vector<int>(vertexNum));
for(int i = 0 ; i < vertexNum ; i++)
for (int j = 0; j < vertexNum; j++) {
adjacencyMatrix[i][j] = *(vertexArray + i*vertexNum + j);
if (adjacencyMatrix[i][j] < INT_MAX)
arcNum++;
}
this->arcNum = arcNum / 2;
}
template<class T>
void Graph<T>::PrintAdjacencyMatrix() {
cout << "图G的顶点数是:" << vertexNum << endl;
cout << "顶点向量的值是:" << endl;
for (int i = 0; i < graphNodeArray.size(); i++) {
cout << graphNodeArray[i].vertexName << endl;
cout << "图G的边数是" << arcNUm << endl;
for(int i = 0 ; i <adjacencyMatrix.size() ; i++)
for (int j = i + 1; j < adjacencyMatrix.size(); j++) {
for (int j = i + 1; j < adjacencyMatrix.size(); j++)
if (adjacencyMatrix[i][j] < INT_MAX)
cout << "(" << i << "," << j << adjacencyMatrixp[i][j] << ")" << endl;
}
}
}
template<class T>
void Graph<T>::GetVexInfo() {
for (int i = 0; i < graphNodeArray.size(); i++) {
cout << graphNodeArray[i].vertexName << "\n";
}
}
template <class T>
void Graph<T>::SetArc(int vertexFrom, int vertextTo, int arclength) {
if (vertexFrom > vertexNum || vertextTo > vertexNum) throw"位置";
else {
adjacencyMatrix[vertextFrom][vertextTo] = arclength;
adjacencyMatrix[vertexTo][vertextFrom] = arclength;
}
}
template<class T>
void Graph<T>::GerArcInfo() {
for (int i = 0; i < graphNodeArray.size(); i++) {
for (int j = 0; j < i; j++) {
if (adjacencyMatrix[i][j] < INT_MAX)
cout << "从" << graphNodeArray[i].vertexName << "到" << graphNodeArray[i].vertexName
<< "的路径长度为:" << adjacencyMatrix[i][j] << "\n";
}
}
}
template<class T>
void Graph<T>::InsertVex(int position, T name) {
if (position < 0 || position>graphNodeArray.size())
throw"位置不正确";
vector<int> tempRow(graphNodeArray.size(), INT_MAX);
GraphNode tempGraphNode;
tempGraphNode.vertexName = name;
graphNodeArray.insert(graphNodeArray.begin() + position, tempGraphNode);
adjacencyMatrix.insert(adjacencyMatrix.begin() + position, tempRow);
for (unsigned i = 0; i < graphNodeArray.size(); ++i) {
adjacencyMatrix[i].insert(adjacencyMatrix[i].begin() + position, INT_MAX);
}
this->vertexNum = this->vertexNum + 1;
}
template <class T>
void Graph<T>::DeleteVex(int position) {
if (position<0 || position>adjacencyMatrix.size()) throw"位置";
int vertexNum = adjacencyMatrix.size();
if (position > -1) {
graphNodeArray.erase(graphNodeArray.begin() + position);
if (adjacencyMatrix.size() > position) {
adjacencyMatrix.erase(adjacencyMatrix.begin() + position);
}
for (unsigned i = 0; i < adjacencyMatrix.size(); ++i) {
if (adjacencyMatrix[i].size() > position) {
if (adjacencyMatrix[i][position] != INT_MAX) {
this->arcNum = this->arcNum - 1;
}
adjacencyMatrix[i].erase(adjacencyMatrix[i].begin() + position);
}
}
this->vertexNum = this->vertexNum - 1;
}
}
template<class T>
void Graph<T>::DeleteArc(int vertextForm, int vertextTo) {
if (vertextForm > vertexNum || vertextTo > vertexNum) throw"位置";
adjacencyMatrix[vertextForm][vertextTo] =
adjacencyMatrix[vertexTo][vertextForm] = INT_MAX;
this->arcNum = this->arcNum - 1;
}
template <class T>
void Graph<T>::InsetArc(int vertextFrom, int vertextTo, int value) {
if (vertextFrom > vertexNum || vertextTo > vertexNum) throw"位置";
if (adjacencyMatrix[vertextFrom][vertextTo] == INT_MAX) {
adjacencyMatrix[vertextFrom][vertextTo] = value;
adjacencyMatrix[vertextTo][vertextFrom] = value;
cout << "从" << graphNodeArray[vertextFrom].vertexName << "到" << graphNodeArray[vertextTo].vertexName
<< "的路径长度为:" << adjacencyMatrix[vertextFrom][vertextTo] << "\n";
this->arcNum = this->arcNum + 1;
}
else {
cout << "边已经存在!" << endl;
}
}
int main()
{
const int numofVertex = 7;
int cost[numofVertex][numofVertex] = {
{INT_MAX,12,5,11,INT_MAX,INT_MAX,INT_MAX},
{12,INT_MAX,INT_MAX,INT_MAX,33,INT_MAX,INT_MAX},
{5,INT_MAX,INT_MAX,21,INT_MAX,19,INT_MAX},
{11,INT_MAX,21,INT_MAX,28,8,INT_MAX},
{INT_MAX,33,INT_MAX,28,INT_MAX,INT_MAX,6},
{INT_MAX,INT_MAX,19,8,INT_MAX,INT_MAX,16},
{INT_MAX,INT_MAX,INT_MAX,INT_MAX,6,16,INT_MAX}
};
string verName[numofVertex] = { "A","B","C","D","E","F","G" };
Graph<string> g(*cost, verName, numofVertex);
int source;
cout << "请输入Prim算法初始顶点:" << "\n";
cin >> source;
try {
g.Prim(source);
}
catch (char *) {
cout << "Prim 算法计算失败" << endl;
}
system("pause");
return 0;
}