图的类定义,Kruskal算法求最小生成树
graph.h中-----------------------------------------
#ifndef GRAPH_H
#define GRAPH_H
class Graph
{
private:
int n;
int A[10][10];
public:
//图的初始化
Graph(int len = 10);
int getvertex(){ return n;}
int countEdges();
void insertEdge(int v1, int v2, int weight);
void deleteEdge(int v1, int v2);
void drawGraph();
//判断图的连通性
void throughDFS(int v);
bool through();
//Kruskal算法
Graph* kruskal(Graph* &g);
bool cycleDetectionDFS(int v);
bool cycleDetection();
int seekMin(int m);
//Dijkstra算法
Graph* Dijkstra(Graph* &g);
int seekMax(int m);
//图的输出
void DFS(int v);
void DepthFirstSearch();
void printEdges();
};
#endif
graph.cpp中--------------------------------------
#include"graph.h"
#include
using namespace std;
//图的初始化---------------------------------------------------------------------
Graph::Graph(int len)
{
n = len;
for(int i= 1; i<=n; i++)
for(int j=1; j<=n; j++)
A[i][j] = 1000;
}
int Graph::countEdges() //边数
{
int number = 0;
for(int i=1;i<=n;i++)
for(int j=1;j if(A[i][j] < 1000)
number++;
return number;
}
void Graph::insertEdge(int v1, int v2, int weight) //添加边
{
if(v1>0 && v1<=n && v2>0 && v2<=n){
A[v1][v2] = weight; //无向图,邻接矩阵沿对角线对称
A[v2][v1] = weight;
}
}
void Graph::deleteEdge(int v1, int v2) //删除边
{
if(v1>0 && v1<=n && v2>0 && v2<=n && A[v1][v2]<1000){
A[v1][v2] = 1000;
A[v2][v1] = 1000;
}
}
void Graph::drawGraph() //画图
{
int v1, v2, w, t = 1;
cout<<"你要在哪两个顶点之间画边?\n请输入顶点对及边的权值(输入完毕按0 0):"< cout<<"("<>v1>>v2;
while(v1!=0 && v2!=0)
{
cout<<" 权值 = ";
cin>>w;
insertEdge(v1, v2, w);
cout<<"("<<++t<<"), ";cin>>v1>>v2;
}
}
//判断图的连通性-----------------------------------------------------------------
int visited[10], counter, edges[10][10];
void Graph::throughDFS(int v)
{
visited[v] = 1;
for(int i=1;i<=n;i++)
if(A[v][i]<1000 && visited[i] == 0)
throughDFS(i);
}
bool Graph::through()
{
counter = 0;
for(int i=1;i<=n;i++)
visited[i] = 0;
for(int j=1;j if(visited[j]==0)
{
counter++;
throughDFS(j);
}
if(counter == 1)
return true;
else
return false;
}
//Kruskal算法的子函数------------------------------------------------------------
bool Graph::cycleDetection() //环的检测
{
for(int i=1;i<=n;i++)
{
visited[i] = 0;
for(int j=0;j<=n;j++)
edges[i][j] = 0;
}
return cycleDetectionDFS(1);
}
bool Graph::cycleDetectionDFS(int v)
{
visited[v] = 1;
for(int i=1; i<=n; i++)
if(A[v][i]<1000)
{
if(visited[i] == 0)
{
visited[i] = 1;
edges[v][i] = 1;
cycleDetectionDFS(i);
}
else if(edges[i][v] == 0)
return true;
}
return false;
}
int Graph::seekMin(int m)//寻找大于m的最小权值
{
int i, j, min = 1000;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
if(A[i][j]m)
min = A[i][j];
return min;
}
//另一种方法:Kruskal算法镜像的子函数-------------------------------------------------------------------
int Graph::seekMax(int m)//寻找小于m的最大权值
{
int i, j, max = 0;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
if(A[i][j]>max && A[i][j] max = A[i][j];
return max;
}
//图的输出----------------------------------------------------------------------
void Graph::DepthFirstSearch() //图的深度优先遍历
{
for(int i=1;i<=n;i++)
visited[i] = 0;
for(int j=1;j<=n;j++)
if(visited[j]==0)
DFS(j);
}
void Graph::DFS(int v)
{
cout< visited[v] = 1;
for(int i=1;i<=n;i++)
if(A[v][i]<1000 && visited[i]==0)
DFS(i);
}
void Graph::printEdges() //输出边集
{
cout<<"边集为:";
for(int i=1;i<=n;i++)
for(int j=n;j>=i;j--)
if(A[i][j] < 1000)
cout<<"("< cout< }
kruskal.cpp中------------------------------------
#include"graph.h"
Graph * Graph::kruskal(Graph* &g)
{
int i, j, side = 0, min = 0;
while(side < n-1)
{ //控制循环:共加入n-1条边
min = seekMin(min);//找权比min大的最小边
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
if(A[i][j] == min)
{
g->insertEdge(i, j, min);
side++;
if(g->cycleDetection())
{ //判断是否成环
g->deleteEdge(i, j);
side--;
}
}
}
return g;
}
similarDijkstra.cpp中-----------------------------------
#include"graph.h"
Graph* Graph::Dijkstra( Graph* &g)
{
int i, j, side = g->countEdges(), max = 1000;
while(side > n-1)
{ //控制循环:直到剩下n-1条边
max = g->seekMax(max);//找权比max小的最大边
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
if(A[i][j] == max)
{
g->deleteEdge(i, j);
side--;
if(!g->through()) //如不连通则将其加回
{
g->insertEdge(i, j, max);
side++;
}
}
}
return g;
}
main.cpp中--------------------------------------
#include"graph.h"
#include
using namespace std;
void main()
{
int v;
cout<<"-----------------------图的构造-------------------------------";
cout<<"\n请输入图的顶点数( < 10 ): N(v) = ";
cin>>v;
Graph graph(v);
Graph minTree(v);
Graph *g = &minTree;
graph.drawGraph();
cout<<"您画的图的深度优先遍历结果为:";
graph.DepthFirstSearch();
cout< graph.printEdges();
if(!graph.through())
{
cout<<"\n您画的不是连通图,无最小生成树!"< exit(1);
}
else
{
char a;
cout<<"---------------------求最小生成树-----------------------------";
cout<<"\n请选择应用哪一种方法求最小生成树( k = Kruskal, d = similarDijkstra):";
cin>>a;
if(a=='k' || a=='K')
{
cout<<"\n应用Kruskal算法求得最小生成树,其深度优先遍历结果为:";
g = graph.kruskal(g);
g->DepthFirstSearch();
cout< g->printEdges();
cout< }
else if(a=='d' || a=='D')
{
minTree = graph;
cout<<"\n应用Dijkstra算法求得最小生成树,其深度优先遍历结果为:";
g = graph.Dijkstra(g);
g->DepthFirstSearch();
cout< g->printEdges();
cout< }
else
{
cout<<"无此种方法!";
exit(1);
}
}
}