圖的鄰接矩陣的C++實現
該程式實現的主要是無向圖。
實現圖這樣的資料結構,透徹理解圖的性質是很重要的。在弄明白了圖的性質後再結合一些常見的程式設計思想,完成無向圖的鄰接矩陣應該不是很難。
// Graph1.h: interface for the Graph1 class.
//
//////////////////////////////////////////////////////////////////////
/********************************************************************/
/*************************圖的鄰接矩陣實現類的定義**********************/
#if !defined(AFX_GRAPH1_H__9F7EFFB9_7EC7_41F1_B9FC_597FC68801E7__INCLUDED_)
#define AFX_GRAPH1_H__9F7EFFB9_7EC7_41F1_B9FC_597FC68801E7__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include<set>
using namespace std;
#define MaxEdges 40
#define MaxNode 30
#define Max 100000
class Graph1
{
private:
int nodecount;
int edgecount;
int a[MaxNode];
//set<int> a;
int b[MaxNode][MaxNode];
public:
Graph1(int);//建構函式
int getNodeCount();//當前的節點數
int getEdgeCount();//當前的邊數
void insertNode(int);//插入一個節點
void isertEdge(int ,int ,int);//插入一條邊
void deleteEdge(int,int);//刪除一條邊
void prim(int);//生成最小樹
int DFS(int);//深度優先搜尋
void DFS(int node,int v[],int& n);
void BFS(int);//廣度優先搜尋
bool isliantong();//判斷是否連通
void liantongfenliang();//連通分量的數目
int getWeight(int,int);//獲得某條邊的權值
int getFirstNeighbor(int);//獲得所給頂點的第一個相鄰節點
int getNextNeighbor(int,int);//獲得某一鄰接節點的下一個鄰接節點
};
#endif // !defined(AFX_GRAPH1_H__9F7EFFB9_7EC7_41F1_B9FC_597FC68801E7__INCLUDED_)
/********************************************************************************/
/********************************圖的實現*****************************************/
// Graph1.cpp: implementation of the Graph1 class.
//
//////////////////////////////////////////////////////////////////////
#include "Graph1.h"
#include <queue>
#include <stack>
#include<iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Graph1::Graph1(int s=MaxNode)//建構函式
{
for(int i=0;i<=s-1;i++)
for(int j=0;j<=s-1;j++)
b[i][j]=0;
nodecount=0;
for(int k=0;k<=s-1;k++)
a[k]=-1;
}
int Graph1::getNodeCount()//當前的節點數
{
return nodecount;
}
int Graph1::getEdgeCount()//當前的邊數
{
return edgecount;
}
void Graph1::insertNode(int it)//插入一個節點
{
//a[nodecount++]=it;
//a.insert(it);
a[it]=it;
nodecount++;
}
void Graph1::isertEdge(int x,int y,int w)//插入一條邊
{
b[x][y]=w;
b[y][x]=w;
cout<<"該邊插入成功! "<<endl;
edgecount++;
}
void Graph1::deleteEdge(int x ,int y)//刪除一條邊
{
b[x][y]=0;
b[y][x]=0;
cout<<"邊("<<x<<","<<y<<")已經成功刪除!";
edgecount--;
}
void Graph1::prim(int x)//生成最小樹
{
int* d=new int[getNodeCount()];
for(int id=0;id<=getNodeCount()-1;id++)
d[id]=0;
int e[10][10];
for(int im=0;im<=9;im++)
for(int rm=0;rm<=9;rm++)
e[im][rm]=0;
int min;
int node;
int l,r;
d[x]=1;
for(int i=1;i<=nodecount-1;i++)
{
min=Max;
for(int j=0;j<=nodecount-1;j++)
if(d[j]==1&&a[j]==j)
{
for(int k=0;k<=nodecount-1;k++)
if(a[k]==k&&d[k]==0&&b[j][k]>0&&b[j][k]<min)
{
node=k;
l=j;
r=k;
//e[a[j]][a[k]]=1;
min=b[l][r];
//d[a[k]]
}
}
d[node]=1;
e[l][r]=b[l][r];
}
//}
for(int ln=0;ln<=9;ln++)
for(int rn=0;rn<=9;rn++)
if(e[ln][rn]>0)
cout<<"("<<ln<<","<<rn<<",權值為"<<e[ln][rn]<<") ,";
}
void Graph1::BFS(int x)//廣度優先搜尋
{
int* v=new int[getNodeCount()];
for(int i=0;i<=getNodeCount()-1;i++)
v[i]=0;
cout<<x<<" ";
v[x]=1;
queue<int> q;
q.push(x);
int next;
while(!q.empty())
{//cout<<"!!!"<<endl;
//x=
x=q.front();
q.pop();
next=getFirstNeighbor(x);
//if(a[next]==-1)
// continue;
while(next!=-1)
{ if(!v[next]&&a[next]==next)
{
cout<<next<<" ";
v[next]=1;
q.push(next);
}
next=getNextNeighbor(x,next);
}
}
delete[] v;
}
// }
void Graph1::DFS(int node,int v[],int& n)
{
cout<<node<<" ";
n++;
v[node]=1;
int next=getFirstNeighbor(node);
while(next!=-1)
{
if(a[next]==next&&!v[next])
DFS(next,v,n);
next=getNextNeighbor(node,next);
}
}
int Graph1::DFS(int node)
{
int n=0;
int* v=new int[nodecount];
for(int i=0;i<=nodecount-1;i++)
v[i]=0;
DFS(node,v,n);
delete[] v;
return n;
}
bool Graph1::isliantong()//判斷是否連通
{
int n=0;
n=DFS(0);
cout<<"該圖的總節點數為:"<<nodecount<<"!"<<endl;
cout<<"其中一個連通分量連通的節點數為:"<<n<<"!"<<endl;
if(n==nodecount)
return true;
else return false;
}
void Graph1::liantongfenliang()//連通分量的數目
{
int n=0;
int* v=new int[nodecount];
for(int i=0;i<=nodecount-1;i++)
v[i]=0;
for(int j=0;j<=nodecount-1;j++)
if(a[j]==j&&!v[j]){
cout<<"(";
DFS(j,v,n);
cout<<") ";
//newliantong();
}
delete[] v;
}
int Graph1::getWeight(int x,int y)//獲得某條邊的權值
{
return b[x][y];
}
int Graph1::getFirstNeighbor(int x)//獲得所給頂點的第一個相鄰節點
{
int n=-1;
if(nodecount==0)
return -1;
for(int i=0;i<=nodecount-1;i++)
if(b[x][i]!=0)
{ n=a[i];
//cout<<n<<"!!"<<endl;
break;
}
return n;
}
int Graph1::getNextNeighbor(int x,int y)//獲得某一鄰接節點的下一個鄰接節點
{
if(y==nodecount-1)
return -1;
int n=-1;
for(int i=y+1;i<=nodecount-1;i++)
if(b[x][i]!=0)
{
n=i;
break;
}
return n;
}
/*********************************************************************************/
/************************************主函式測試************************************/
#include "Graph1.h"
#include<iostream>
using namespace std;
int main(){
Graph1 G(10);
cout<<"你好,請問你向圖新增幾個節點?請從鍵盤輸入!"<<endl;
int n;
cin>>n;
cout<<"請輸入你要插入的"<<n<<"個節點!"<<endl;
int node;
for(int i=0;i<=n-1;i++)
{
cin>>node;
G.insertNode(node);
}
cout<<"恭喜你!你已經向圖中成功新增節點!"<<endl;
cout<<"你好,請問你向圖中新增幾條邊?請從鍵盤輸入!"<<endl;
int e;
cin>>e;
cout<<"請輸入你要新增的"<<e<<"條邊以及邊上對應的權值!"<<endl;
int x,y,w;
for(int j=0;j<=e-1;j++)
{cin>>x>>y>>w;
G.isertEdge(x,y,w);
}
cout<<"恭喜你!你的圖已經建立成功!"<<endl;
cout<<"請輸入你要查詢有邊相鄰的節點!"<<endl;
cin>>node;
cout<<"相鄰節點為"<<G.getFirstNeighbor(node)<<endl;
cout<<"第二個相鄰節點為"<<G.getNextNeighbor(node,G.getFirstNeighbor(node))<<endl;
cout<<"***********************"<<endl;
cout<<"*請選擇你要進行的操作:*"<<endl;
cout<<"*1--表示插入新節點! *"<<endl;
cout<<"*2--表示刪除邊! *"<<endl;
cout<<"*3--表示深度優先搜尋! *"<<endl;
cout<<"*4--表示廣度優先搜尋! *"<<endl;
cout<<"*5--表示求最小生成樹! *"<<endl;
cout<<"*6--判斷圖是否連通! *"<<endl;
cout<<"*7--求圖的連通分量! *"<<endl;
cout<<"*8--插入新的邊! *"<<endl;
cout<<"*0--表示結束操作! *"<<endl;
cout<<"***********************"<<endl;
int choice;
while(true)
{
cout<<endl;
cout<<"請你做出選擇!"<<endl;
cin>>choice;
switch(choice)
{
case 1:
cout<<"請輸入你要插入的新節點!"<<endl;
cin>>node;
//G.deleteNode(node);
G.insertNode(node);
cout<<endl;
break;
case 2:
cout<<"請輸入你要刪除的邊!"<<endl;
cin>>x>>y;
G.deleteEdge(x,y);
cout<<endl;
break;
case 3:
cout<<"請輸入你選擇的起始節點!"<<endl;
cin>>node;
cout<<"深度優先搜尋結果為:"<<endl;
G.DFS(node);
cout<<endl;
break;
case 4:
cout<<"請輸入你選擇的起始節點!"<<endl;
cin>>node;
cout<<"廣度優先搜尋結果為:"<<endl;
G.BFS(node);
cout<<endl;
break;
case 5:
cout<<"請輸入你選擇的起始節點!"<<endl;
cin>>node;
cout<<"最小生成樹為:"<<endl;
G.prim(node);
cout<<endl;
break;
case 6:
if(G.isliantong())
cout<<"該圖是連通的!"<<endl;
else cout<<"該圖不是連通的!"<<endl;
break;
case 7:
cout<<"圖的連通分量為:"<<endl;
G.liantongfenliang();
cout<<endl;
break;
case 8:
cout<<"請輸入你要新增的"<<e<<"條邊以及邊上對應的權值!"<<endl;
cin>>x>>y>>w;
G.isertEdge(x,y,w);
break;
case 0:
cout<<"謝謝,測試完成!"<<endl;
return 0;
}
}
}