基於鄰接矩陣實現簡單圖的一些基本操作
偶爾記錄一下,原來圖的算法也沒有那麼難,廢話不多說,直接上代碼
C/C++ 代碼:
MGraph.h 代碼:
#include<iostream>
#include<cstring>
#include<climits>
#include"LinkQueue.h"
using namespace std;
#define INFINITY_CHAR "∞"
#define INFINITY INT_MAX
#define MAX_VERTEX_SIZE 20
#ifndef __MGRAPH_H__
#define __MGRAPH_H__
template <class V, class E> struct MGraph {
int vexnum; //頂點數量
int arcnum; //邊的數量
bool isWeighted; //是否是帶權圖
bool isUndir; //是否無向圖
V vex[MAX_VERTEX_SIZE];
E edge[MAX_VERTEX_SIZE][MAX_VERTEX_SIZE];
};
template <class V, class E> void InitMGraph(MGraph<V, E> &g) {
g.vexnum = 0;
g.arcnum = 0;
g.isWeighted = false;
g.isUndir = true;
memset(g.vex, 0, sizeof(g.vex));
memset(g.edge, 0, sizeof(g.edge));
}
template <class V, class E> void InitMGraph(MGraph<V, E> &g, bool isWeighted) {
InitMGraph(g);
if(isWeighted) {
g.isWeighted = isWeighted;
for(int i = 0; i < MAX_VERTEX_SIZE; i++) {
for(int j = 0; j < MAX_VERTEX_SIZE; j++) {
g.edge[i][j] = INFINITY;
}
}
}
}
//創建圖,提示很簡單,畢竟英語很渣,就不打註釋了
template <class V, class E> void CreateMGraph(MGraph<V, E> &g) {
char ch;
V x, y;
E z = 1;
cout<<"Do you want to create a weighted graph ? (y / n) ";
cin>>ch;
InitMGraph(g, ch == 'y' || ch == 'Y');
cout<<"Do you want to create a undirected graph ? (y / n) ";
cin>>ch;
g.isUndir = ch == 'y' || ch == 'Y' ? true : false;
cout<<"Please input the number of vertices and edges: ";
cin>>g.vexnum>>g.arcnum;
cout<<"Please input vertices:"<<endl;
for(int i = 0; i < g.vexnum; i++) {
cin>>g.vex[i];
}
cout<<"Please input a pair of adjacent points (and weight if necessary):"<<endl;
for(int k = 0; k < g.arcnum; k++) {
cin>>x>>y;
if(g.isWeighted) {
cin>>z;
}
int i = LocateVex(g, x);
int j = LocateVex(g, y);
g.edge[i][j] = z;
if(g.isUndir) {
g.edge[j][i] = z;
}
}
cout<<"Create MGraph success!"<<endl;
}
template <class V> void visit(V v) {
cout<<v<<" ";
}
template <class V, class E> void PrintMGraph(MGraph<V, E> g) {
cout<<"Vertexs:"<<endl;
for(int i = 0; i < g.vexnum; i++) {
cout<<g.vex[i]<<"\t";
}
cout<<endl<<"Adjacent matrix:"<<endl;
for(int i = 0; i < g.vexnum; i++) {
for(int j = 0; j < g.vexnum; j++) {
if(g.edge[i][j] == INFINITY) {
cout<<INFINITY_CHAR<<"\t";
} else {
cout<<g.edge[i][j]<<"\t";
}
}
cout<<endl;
}
cout<<endl;
}
template <class V, class E> int LocateVex(MGraph<V, E> g, V v) {
int index = g.vexnum - 1;
while(index > -1 && v != g.vex[index]) {
index--;
}
return index;
}
template <class V, class E> bool Adjacent(MGraph<V, E> g, V v1, V v2) {
int i = LocateVex(g, v1);
int j = LocateVex(g, v2);
if(i == -1 || j == -1) {
return false;
}
return g.isWeighted ? g.edge[i][j] != INFINITY : g.edge[i][j] != 0;
}
template <class V, class E> V FirstAdjVex(MGraph<V, E> g, V v) {
int index = LocateVex(g, v);
if(index == -1) {
return NULL;
}
for(int i = 0; i < g.vexnum; i++) {
if(Adjacent(g, v, g.vex[i])) {
return g.vex[i];
}
}
return NULL;
}
template <class V, class E> V NextAdjVex(MGraph<V, E> g, V v1, V v2) {
if(!Adjacent(g, v1, v2)) {
return NULL;
}
for(int i = LocateVex(g, v2) + 1; i < g.vexnum; i++) {
if(Adjacent(g, v1, g.vex[i])) {
return g.vex[i];
}
}
return NULL;
}
template <class V, class E> void BFS(MGraph<V, E> g, V v, bool *isVisit) {
visit<V>(v);
isVisit[LocateVex(g, v)] = true;
LinkQueue<V> *q;
InitQueue(q);
EnQueue(q, v);
while(!QueueEmpty(q)) {
DeQueue(q, v);
for(V w = FirstAdjVex(g, v); w != NULL; w = NextAdjVex(g, v, w)) {
if(!isVisit[LocateVex(g, w)]) {
visit<V>(w);
isVisit[LocateVex(g, w)] = true;
EnQueue(q, w);
}
}
}
}
template <class V, class E> void BFS(MGraph<V, E> g) {
bool *isVisit = new bool[g.vexnum] {false};
for(int i = 0; i < g.vexnum; i++) {
if(!isVisit[i]) {
BFS(g, g.vex[i], isVisit);
}
}
}
template <class V, class E> void DFS(MGraph<V, E> g, V v, bool *isVisit) {
visit<V>(v);
isVisit[LocateVex(g, v)] = true;
for(V w = FirstAdjVex(g, v); w != NULL; w = NextAdjVex(g, v, w)) {
if(!isVisit[LocateVex(g, w)]) {
DFS(g, w, isVisit);
}
}
}
template <class V, class E> void DFS(MGraph<V, E> g) {
bool *isVisit = new bool[g.vexnum] {false};
for(int i = 0; i < g.vexnum; i++) {
if(!isVisit[i]) {
DFS(g, g.vex[i], isVisit);
}
}
}
#endif
LinkQueue.h 代碼:
#include<iostream>
#include<malloc.h>
using namespace std;
#ifndef __LINKQUEUE_H__
#define __LINKQUEUE_H__
template <class T> struct LinkNode {
T data;
struct LinkNode *next;
};
template <class T> struct LinkQueue {
struct LinkNode<T> *front;
struct LinkNode<T> *rear;
};
template <class T> void InitQueue(LinkQueue<T> *&queue) {
//帶頭結點,front -> next 爲隊頭元素,空隊列條件爲:front == rear
//不帶頭結點空隊列條件爲:front == NULL && read == NULL
queue = (LinkQueue<T> *)malloc(sizeof(LinkQueue<T>));
LinkNode<T> *p = (LinkNode<T> *)malloc(sizeof(LinkNode<T>));
p -> next = NULL;
queue -> front = p;
queue -> rear = p;
}
template <class T> bool QueueEmpty(LinkQueue<T> *queue) {
return queue == NULL ? true : queue -> front == queue -> rear;
}
template <class T> int QueueLength(LinkQueue<T> *queue) {
int length = -1;
LinkNode<T> *p = queue -> front;
while(p != NULL) {
length++;
p = p -> next;
}
return length;
}
template <class T> bool EnQueue(LinkQueue<T> *queue, T e) {
LinkNode<T> *p = (LinkNode<T> *)malloc(sizeof(LinkNode<T>));
if(p == NULL) {
return false;
}
p -> data = e;
p -> next = NULL;
queue -> rear -> next = p;
queue -> rear = p;
return true;
}
template <class T> bool DeQueue(LinkQueue<T> *queue, T &x) {
if(QueueEmpty(queue)) {
return false;
}
LinkNode<T> *p = queue -> front -> next;
x = p -> data;
queue -> front -> next = p -> next;
if(queue -> rear == p) {
//隊尾出隊
queue -> rear = queue -> front;
}
free(p);
return true;
}
template <class T> bool GetHead(LinkQueue<T> *queue, T &x) {
if(QueueEmpty(queue)) {
return false;
}
x = queue -> front -> next -> data;
return true;
}
template <class T> void DestroyQueue(LinkQueue<T> *queue) {
LinkNode<T> *p = queue -> front;
while(p != NULL) {
queue -> front = p -> next;
free(p);
p = queue -> front;
}
free(queue);
}
template <class T> void PrintQueue(LinkQueue<T> *queue) {
if(QueueEmpty(queue)) {
return ;
}
LinkNode<T> *p = queue -> front -> next;
while(p != NULL) {
cout<<p -> data<<" ";
p = p -> next;
}
cout<<endl;
}
#endif