C++鄰接表與無向圖
參考《算法》,採用鄰接表實現圖結構,實現DFS以及BFS等算法。具體原理參考書本,此處給出C++版本實現。
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
using namespace std;
/*
頂點 中間節點
VNode ENode
0 | A --> 2(C) 1(B)
1 | B --> 4(E) 3(D) 0(A)
2 | C --> 6(G) 5(F) 0(A)
3 | D --> 7(H) 1(B)
4 | E --> 7(H) 1(B)
5 | F --> 6(G) 2(C)
6 | G --> 5(F) 2(C)
7 | H --> 4(E) 3(D)
*/
const int MAX = 20;
struct ENode //鄰接表的中間節點
{
int adjvex; //對應索引
ENode* next;
};
typedef struct VNode //鄰接表頂點
{
char vertex; //值
ENode* firstarc; //指向第一個中間節點
}AdjList[MAX];
class ALGraph //圖
{
private:
AdjList adjList; //鄰接表數組
int vexNum; //節點數量
int arcNum; //連邊數量
bool visited[MAX]; //標記被訪問
map<int,int> unionfield; //標記節點屬於哪個連通域
public:
void CreateGraph(); //創建圖
void PrintGraph(); //打印圖
void DFS(int v,int field); //深度優先搜索
void BFS(); //廣度優先搜索
int DFS_findUnion(); //深度優先搜索尋找連通域
bool isConnect(int m,int n); //判斷兩個節點是否連通
};
void ALGraph::CreateGraph()
{
cout << "請輸入圖的頂點數:" << endl;
cin >> this->vexNum;
cout << "請輸入圖的弧數:" << endl;
cin >> this->arcNum;
cout << "請輸入頂點信息:" << endl;
for (int i = 0; i<this->vexNum; i++) //構建頂點數組
{
cin >> this->adjList[i].vertex;
this->adjList[i].firstarc = nullptr;
}
cout << "請輸入" << this->arcNum << "個弧的信息:" << endl;
for (int i = 0; i<this->arcNum; i++) //構建每條鄰接表
{
int h1, h2;
cin >> h1 >> h2;
ENode* temp = new ENode();
temp->adjvex = h2;
temp->next = this->adjList[h1].firstarc;
this->adjList[h1].firstarc = temp;
temp = new ENode();
temp->adjvex = h1;
temp->next = this->adjList[h2].firstarc;
this->adjList[h2].firstarc = temp;
}
}
void ALGraph::PrintGraph()
{
for (int i = 0; i<this->vexNum; i++)
{
cout << this->adjList[i].vertex << "--------->";
ENode* p = this->adjList[i].firstarc;
while (p)
{
cout << this->adjList[p->adjvex].vertex << " ";
p = p->next;
}
cout << endl;
}
}
void ALGraph::BFS()
{
for(int i=0;i<this->vexNum;i++)
{
visited[i] = false;
}
queue<int> q;
for(int i=0;i<this->vexNum;i++)
{
if(!visited[i])
{
visited[i] = true;
q.push(i);
cout<<this->adjList[i].vertex<<" ";
while(!q.empty())
{
int x = q.front();
q.pop();
ENode* p = this->adjList[x].firstarc;
while(p)
{
if(!visited[p->adjvex])
{
visited[p->adjvex] = true;
cout<<this->adjList[p->adjvex].vertex<<" ";
q.push(p->adjvex);
}
p = p->next;
}
}
}
}
}
void ALGraph::DFS(int v,int field)
{
visited[v] = true;
this->unionfield.insert(make_pair(v, field));
cout << this->adjList[v].vertex << " ";
ENode* p = this->adjList[v].firstarc;
while (p)
{
if (!visited[p->adjvex])
DFS(p->adjvex,field);
p = p->next;
}
}
int ALGraph::DFS_findUnion()
{
this->unionfield.clear();
int count = 0; //連通域個數
for(int i=0;i<this->vexNum;i++)
{
visited[i] = false;
}
cout<<"各個連通域如下所示:"<<endl;
for(int i=0;i<this->vexNum;i++)
{
if(!visited[i])
{
DFS(i,++count);
cout<<endl;
}
}
cout<<endl;
return count;
}
bool ALGraph::isConnect(int m,int n)
{
return (this->unionfield[m]==this->unionfield[n])?true:false;
}
int main()
{
ALGraph* graph = new ALGraph();
graph->CreateGraph();
cout<<graph->DFS_findUnion()<<"個連通域"<<endl;
cout<<"連通情況爲:"<<graph->isConnect(6, 7)<<endl;
return 0;
}