代码示例:
#ifndef NODE_H
#define NODE_H
class Node
{
public:
Node(char data=0);
char m_cData;
bool m_bIsVisited;
};
#endif
#include"Node.h"
Node::Node(char data)
{
m_cData=data;
m_bIsVisited=false;
}
#ifndef EDGE_H
#define EDGE_H
class Edge
{
public:
Edge(int nodeIndexA=0,int nodeIndexB=0,int weightValue=0);
int m_iNodeIndexA;
int m_iNodeIndexB;
int m_iWeightValue;
bool m_bSelected;
};
#endif
#include"Edge.h"
Edge::Edge(int nodeIndexA,int nodeIndexB,int weightValue)
{
m_iNodeIndexA=nodeIndexA;
m_iNodeIndexB=nodeIndexB;
m_iWeightValue=weightValue;
m_bSelected=false;
}
#ifndef CMAP_H
#define CMAP_H
#include
using namespace std;
#include"Node.h"
#include"Edge.h"
class CMap
{
public:
CMap(int capacity);
~CMap();
bool addNode(Node*pNode);//向图中加入顶点(结点)
void resetNode();//重置顶点
bool setValueToMatrixForDirectedGraph(int row,int col,int val=1);//为有向图设置邻接矩阵
bool setValueToMatrixForUndirectedGraph(int row,int col,int val=1);//为无向图设置邻接矩阵
void printMatrix();//打印临接矩阵
void depthFirstTraverse(int nodeIndex);//深度优先遍历
void breadthFirstTraverse(int nodeIndex);//广度优先遍历
void primTree(int nodeIndex);//普里姆算法生成树
void kruskalTree();//克鲁斯卡尔算法生成树
private:
bool getValueFromMatrix(int row,int col,int &val);//从矩阵中获取权值
void breadthFirstTraverseImpl(vector<int>preVec);//广度优先遍历实现函数
int getMinEdge(vector<Edge>edgeVec);
bool isInSet(vector<int>nodeSet,int target);//判断顶点是否在集合中
void mergeNodeSet(vector<int> &nodeSetA,vector<int> nodeSetB);//合并两个点集合
private:
int m_iCapacity;//图中最多可以容纳的定点数
int m_iNodeCount;//已经添加的顶点(结点)个数
Node*m_pNodeArray;//用来存放的数组
int *m_pMatrix;//用来存放邻接矩阵
Edge*m_pEdge;
};
#endif
#include"CMap.h"
#include
#include
using namespace std;
CMap::CMap(int capacity)
{
m_iCapacity=capacity;
m_iNodeCount=0;
m_pNodeArray=new Node[m_iCapacity];
m_pMatrix=new int[m_iCapacity*m_iCapacity];
//memset(m_pMatrix,0,m_iCapacity*m_iCapacity*sizeof(int));
m_pEdge=new Edge[m_iCapacity-1];
for(int i=0;i<m_iCapacity*m_iCapacity;i++)
{
m_pMatrix[i]=0;
}
}
CMap::~CMap()
{
delete []m_pNodeArray;
m_pNodeArray=NULL;
delete []m_pMatrix;
m_pMatrix=NULL;
delete []m_pEdge;
m_pEdge=NULL;
}
bool CMap::addNode(Node*pNode)
{
if(pNode==NULL)
{
return false;
}
m_pNodeArray[m_iNodeCount].m_cData= pNode->m_cData;
m_iNodeCount++;
return true;
}
void CMap::resetNode ()
{
for(int i=0;i<m_iNodeCount;i++)
{
m_pNodeArray[i].m_bIsVisited=false;
}
}
bool CMap::setValueToMatrixForDirectedGraph(int row,int col,int val) //有向图
{
if(row<0||row>=m_iCapacity)
{
return false;
}
if(col<0||col>=m_iCapacity)
{
return false;
}
m_pMatrix[row*m_iCapacity+col]=val;
return true;
}
bool CMap::setValueToMatrixForUndirectedGraph(int row,int col,int val) //无向图
{
if(row<0||row>=m_iCapacity)
{
return false;
}
if(col<0||col>=m_iCapacity)
{
return false;
}
m_pMatrix[row*m_iCapacity+col]=val;
m_pMatrix[col*m_iCapacity+row]=val;
return true;
}
void CMap::printMatrix()
{
for(int i=0;i<m_iCapacity;i++)
{
for(int k=0;k<m_iCapacity;k++)
{
cout<< m_pMatrix[i*m_iCapacity+k]<<" ";//row
}
cout<<endl;
}
}
void CMap::depthFirstTraverse(int nodeIndex)
{
int value=0;
cout<<m_pNodeArray[nodeIndex].m_cData<<" ";
m_pNodeArray[nodeIndex].m_bIsVisited=true;
for(int i=0;i<m_iCapacity;i++)
{
getValueFromMatrix(nodeIndex,i,value);
if(value==1)
{
if(m_pNodeArray[i].m_bIsVisited==true)
{
continue;
}
else
{
depthFirstTraverse(i);
}
}
else
{
continue;
}
}
}
bool CMap::getValueFromMatrix(int row,int col,int &val)
{
if(row<0||row>=m_iCapacity)
{
return false;
}
if(col<0||col>=m_iCapacity)
{
return false;
}
val=m_pMatrix[row*m_iCapacity+col];
return true;
}
void CMap::breadthFirstTraverse(int nodeIndex)
{
cout<<m_pNodeArray[nodeIndex].m_cData<<" ";
m_pNodeArray[nodeIndex].m_bIsVisited=true;
vector<int>curVec;
curVec.push_back(nodeIndex);
breadthFirstTraverseImpl(curVec);
}
void CMap::breadthFirstTraverseImpl(vector<int>preVec)
{
int value=0;
vector<int>curVec;
for(int j=0;j<(int)preVec.size();j++)
{
for(int i=0;i<m_iCapacity;i++)
{
getValueFromMatrix(preVec[j],i,value);
if(value!=0)
{
if(m_pNodeArray[i].m_bIsVisited)
{
continue;
}
else
{
cout<<m_pNodeArray[i].m_cData<<" ";
m_pNodeArray[i].m_bIsVisited=true;
curVec.push_back(i);
}
}
}
}
if(curVec.size()==0)
{
return;
}
else
{
breadthFirstTraverseImpl(curVec);
}
}
void CMap::primTree(int nodeIndex)
{
int value=0;
int edgeCount=0;
vector<int>nodeVec;
vector<Edge>edgeVec;
cout<<m_pNodeArray[nodeIndex].m_cData<<endl;
m_pNodeArray[nodeIndex].m_bIsVisited=true;
nodeVec.push_back(nodeIndex);
//所有可选边放入集合中
while(edgeCount<m_iCapacity-1)
{
int temp=nodeVec.back();
for(int i=0;i<m_iCapacity;i++)
{
getValueFromMatrix(temp,i,value);
if(value!=0)
{
if(m_pNodeArray[i].m_bIsVisited)
{
continue;
}
else
{
Edge edge(temp,i,value);
edgeVec.push_back(edge);
}
}
}
//从可选边中选出最小边
int edgeIndex= getMinEdge(edgeVec);
edgeVec[edgeIndex].m_bSelected=true;
cout<<edgeVec[edgeIndex].m_iNodeIndexA<<"--" <<edgeVec[edgeIndex].m_iNodeIndexB<<"--- ";
cout<<edgeVec[edgeIndex].m_iWeightValue<<endl;
m_pEdge[edgeCount]=edgeVec[edgeIndex];
edgeCount++;
int nextNodeIndex=edgeVec[edgeIndex].m_iNodeIndexB;
nodeVec.push_back(nextNodeIndex);
m_pNodeArray[nextNodeIndex].m_bIsVisited=true;
cout<<m_pNodeArray[nextNodeIndex].m_cData<<endl;
}
}
int CMap::getMinEdge(vector<Edge>edgeVec)
{
int minWeight=0;
int edgeIndex=0;
int i=0;
for(;i<(int)edgeVec.size();i++)
{
if(!edgeVec[i].m_bSelected)
{
minWeight=edgeVec[i].m_iWeightValue;
edgeIndex=i;
break;
}
}
if(minWeight==0)
{
return -1;
}
for(;i<(int)edgeVec.size();i++)
{
if(edgeVec[i].m_bSelected)
{
continue;
}
else
{
if(minWeight>edgeVec[i].m_iWeightValue)
{
minWeight=edgeVec[i].m_iWeightValue;
edgeIndex=i;
}
}
}
return edgeIndex;
}
void CMap::kruskalTree()
{
int value=0;
int edgeCount=0;
//定义存放结点集合的数组
vector<vector<int>>nodeSets;
//第一步:取出所有边
vector<Edge>edgeVec;
for(int i=0;i<m_iCapacity;i++)
{
for(int j=i+1;j<m_iCapacity;j++)
{
getValueFromMatrix(i,j,value);
if(value!=0)
{
Edge edge(i,j,value);
edgeVec.push_back(edge);
}
}
}
//第二部:从所选边中取出组成最小生成树的边
//1、找到算法结束条件
while(edgeCount<m_iCapacity-1)
{
//2、从边结合中找到最小边
int minEdgeIndex=getMinEdge(edgeVec);
edgeVec[minEdgeIndex].m_bSelected=true;
//3、找出最小边链接的点
int nodeAIndex=edgeVec[minEdgeIndex].m_iNodeIndexA;
int nodeBIndex=edgeVec[minEdgeIndex].m_iNodeIndexB;
//4、找出点所在的集合
bool nodeAIsInSet=false;
bool nodeBIsInSet=false;
int nodeAInSetLabel=-1;
int nodeBInSetLabel=-1;
for(int i=0;i<(int)nodeSets.size();i++)
{
nodeAIsInSet=isInSet(nodeSets[i],nodeAIndex);
if(nodeAIsInSet)
{
nodeAInSetLabel=i;
}
}
for(int i=0;i<(int)nodeSets.size();i++)
{
nodeBIsInSet=isInSet(nodeSets[i],nodeBIndex);
if(nodeBIsInSet)
{
nodeBInSetLabel=i;
}
}
//5、根据点所在集合不同做出不同处理
if(nodeAInSetLabel==-1&&nodeBInSetLabel==-1)
{
vector<int>vec;
vec.push_back(nodeAIndex);
vec.push_back(nodeBIndex);
nodeSets.push_back(vec);
}
else if(nodeAInSetLabel==-1&& nodeBInSetLabel!=-1)
{
nodeSets[nodeBInSetLabel].push_back(nodeAIndex);
}
else if(nodeBInSetLabel==-1&& nodeAInSetLabel!=-1)
{
nodeSets[nodeAInSetLabel].push_back(nodeBIndex);
}
else if(nodeBInSetLabel!=-1&& nodeAInSetLabel!=-1&&nodeAInSetLabel!=nodeBInSetLabel)
{
mergeNodeSet(nodeSets[nodeAInSetLabel],nodeSets[nodeBInSetLabel]);
for(int k=nodeBInSetLabel;k<(int)nodeSets.size()-1;k++)
{
nodeSets[k]=nodeSets[k+1];
}
}
else if(nodeBInSetLabel!=-1&& nodeAInSetLabel!=-1&&nodeAInSetLabel==nodeBInSetLabel)
{
continue;
}
m_pEdge[edgeCount]=edgeVec[minEdgeIndex];
edgeCount++;
cout<<edgeVec[minEdgeIndex].m_iNodeIndexA<<"--"<<edgeVec[minEdgeIndex].m_iNodeIndexB<<"--";
cout<<edgeVec[minEdgeIndex].m_iWeightValue<<endl;
}
}
bool CMap::isInSet(vector<int>nodeSet,int target)
{
for(int i=0;i<(int)nodeSet.size();i++)
{
if(nodeSet[i]==target)
{
return true;
}
}
return false;
}
void CMap::mergeNodeSet(vector<int> &nodeSetA,vector<int> nodeSetB)
{
for(int i=0;i<(int)nodeSetB.size();i++)
{
nodeSetA.push_back(nodeSetB[i]);
}
}
#include
#include
#include"CMap.h"
using namespace std;
/*
最小生成树kruskal(克鲁斯卡尔)算法
A
/ | \
B---F---E
\ / \ /
C---D
顶点(结点)
A B C D E F
0 1 2 3 4 5
权值部分:
A-B 6 A-E 5 A-F 1
B-C 3 B-F 2
C-F 8 C-D 7
D-F 4 D-E 2
E-F 9
*/
int main(void)
{
CMap*pMap=new CMap(6);
Node*pNodeA=new Node('A');
Node*pNodeB=new Node('B');
Node*pNodeC=new Node('C');
Node*pNodeD=new Node('D');
Node*pNodeE=new Node('E');
Node*pNodeF=new Node('F');
pMap->addNode(pNodeA);
pMap->addNode(pNodeB);
pMap->addNode(pNodeC);
pMap->addNode(pNodeD);
pMap->addNode(pNodeE);
pMap->addNode(pNodeF);
pMap->setValueToMatrixForUndirectedGraph(0,1,6);
pMap->setValueToMatrixForUndirectedGraph(0,4,5);
pMap->setValueToMatrixForUndirectedGraph(0,5,1);
pMap->setValueToMatrixForUndirectedGraph(1,2,3);
pMap->setValueToMatrixForUndirectedGraph(1,5,2);
pMap->setValueToMatrixForUndirectedGraph(2,5,8);
pMap->setValueToMatrixForUndirectedGraph(2,3,7);
pMap->setValueToMatrixForUndirectedGraph(3,5,4);
pMap->setValueToMatrixForUndirectedGraph(3,4,2);
pMap->setValueToMatrixForUndirectedGraph(4,5,9);
pMap->kruskalTree();
system("pause");
return 0;
}