基於鄰接矩陣實現簡單圖的一些基本操作

基於鄰接矩陣實現簡單圖的一些基本操作


偶爾記錄一下,原來圖的算法也沒有那麼難,廢話不多說,直接上代碼

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章