C++ 圖結構鄰接表簡單實現
阿新 • • 發佈:2019-02-12
參照嚴蔚敏老師的《資料結構》一書,第7章實現
圖結構的鄰接表實現方式
表節點:
鄰接點域(adjvex),鏈域(nextarc),資料域(info)。
頭結點:
頂點資訊(data),鏈域(firstarc)。
其中,表頭節點通常以順序結構的形式儲存,以便於隨機訪問任一頂點。
下面是具體的實現:
#ifndef GRAPHMAT_H
#define GRAPHMAT_H
#include <iostream>
using namespace std;
//-----圖的鄰接表儲存表示-----//
#define MAX_VERTEX_NUM 20
typedef struct ArcNode{
ArcNode(int a, int w) :adjvex(a), weight(w), nextarc(NULL){}
ArcNode() :nextarc(NULL){}
int adjvex; //該弧所指向的頂點的位置
int weight; //該弧相關的權值資訊
ArcNode *nextarc; //指向下一條弧的指標
}ArcNode;
typedef struct VNode{
VNode() :date(0), firstarc(NULL){}
int date; //頂點資訊
ArcNode *firstarc; //指向第一條依附該頂點的弧的指標
}VNode,AdjList[MAX_VERTEX_NUM];
class Graph
{
public:
Graph();
~Graph();
private:
AdjList vertices; //圖的鄰接表
int vexnum, arcnum; //圖當前頂點數和弧數
//int kind; //圖的種類標誌
bool isTraver[MAX_VERTEX_NUM]; //圖頂點的遍歷標誌
public:
void BuildGraph(); //構造圖
void DFSTraverse(); //深度遍歷
void BFSTraverse(); //廣度遍歷
private:
void InsertEdge(int i, int a, int w); //插入邊
void DFSFunction(int i);//深度遍歷
void BFSFunction(int i);//廣度遍歷
};
Graph::Graph() :vexnum(0), arcnum(0)
{
for (int i = 0; i < MAX_VERTEX_NUM; i++){
vertices[i].date = -1;
vertices[i].firstarc = NULL;
isTraver[i] = 0;
}
}
Graph::~Graph()
{
}
void Graph::BuildGraph(){
cout << "輸入頂點的個數" << endl;
cin >> vexnum;
cout << "輸入弧的個數" << endl;
cin >> arcnum;
for (int i = 0; i < vexnum; i++){
cout << "輸入第" << i + 1 << "個頂點的資料及邊數" << endl;
cin >> vertices[i].date;
int single_arc_num = 0;
cin >> single_arc_num;
for (int j = 0; j < single_arc_num; j++){
cout << "輸入第" << i + 1 << "個頂點相鄰的表節點的頂點位置以及權值" << endl;
int a = 0, w = 0;
cin >> a >> w;
InsertEdge(i, a, w);
}
}
}
void Graph::InsertEdge(int i, int a, int w){
//新建一個表節點
ArcNode *end = new ArcNode(a, w);
//將第i個單鏈表移動到表尾
ArcNode *temp = vertices[i].firstarc;
if (!temp){
vertices[i].firstarc = end;
return;
}
while (temp){
temp = temp->nextarc;
}
//在尾部插入該表節點
temp = end;
}
void Graph::DFSTraverse(){
//首先將遍歷標誌清空
for (int i = 0; i < MAX_VERTEX_NUM; i++){
isTraver[i] = 0;
}
for (int i = 0; i < vexnum; i++){
if (!isTraver[i]){
DFSFunction(i);
}
}
}
void Graph::DFSFunction(int i){
isTraver[i] = 1;
cout << vertices[i].date << "->";
ArcNode *p = vertices[i].firstarc;
while (p){
int w = p->adjvex;
if (!isTraver[w]){
DFSFunction(w);
}
p = p->nextarc;
}
}
void Graph::BFSTraverse(){
//首先將遍歷標誌清空
for (int i = 0; i < MAX_VERTEX_NUM; i++){
isTraver[i] = 0;
}
for (int i = 0; i < vexnum; i++){
BFSFunction(i);
}
}
void Graph::BFSFunction(int i){
if (!isTraver[i]){
isTraver[i] = 1;
cout << vertices[i].date << "->";
}
ArcNode *p = vertices[i].firstarc;
while (p){
int w = p->adjvex;
if (!isTraver[w]){
isTraver[w] = 1;
cout << vertices[w].date << "->";
}
p = p->nextarc;
}
}
#endif
簡單的測試:
#include "stdafx.h"
#include "Graph.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Graph gra;
gra.BuildGraph();
cout << "深度遍歷結果:" << endl;
gra.DFSTraverse();
cout << "廣度遍歷結果:" << endl;
gra.BFSTraverse();
cout << endl;
return 0;
}
實現效果: