0
点赞
收藏
分享

微信扫一扫

图的周游(C++实现)

        图是一种比线性结构和树形结构更为复杂的数据结构。在这种非线性结构中,结点之间的关系可以是任意的

线性结构:唯一前驱,唯一后继,反映一种线性关系。

树形结构:唯一前驱,多个后继,反映一种层次关系。

图结构:不限制前驱和后继的个数,反映一种网状结构。

所以线性表和树可以看作是受限图。

图的存储:图可以用相邻矩阵(邻接矩阵)表示

图的周游:

        深度优先周游:图的深度优先搜索(DFS)类似于树的先根次序周游,特点是尽可能先对纵深方向进行搜索

        广度优先周游:广度优先搜索的过程类似于树的按层次次序周游。可以使用FIFO队列保存已访问过的顶点,从而使得先访问的顶点的邻接点在下一轮被优先访问到。在搜索过程中,每访问到一个顶点后将其入队,当队头元素出队使将其未被访问的邻接点入队,每个顶点只入队一次

例:对下图进行周游

        相邻矩阵(邻接矩阵):

            0,1,0,0,0,0,0,
            0,0,1,1,0,0,0,
            1,0,0,0,0,0,0,
            1,0,1,0,0,0,0,
            0,0,0,0,0,1,1,
            0,1,0,0,0,0,1,
            0,0,0,1,0,0,0, 

        深度优先周游结果:V0->V1->V2->V3->V4->V5->V6

        广度优先周游结果:V0->V1->V2->V3->V4->V5->V6

代码及说明如下:

编译器:VisualStudio2017

代码文件结构:

 

头文件:

Edge.h

#pragma once
template<class T>
class Edge//边类
{
public:
	int from;//边的始点
	int to;//边的终点
	int weight;//边的权值
	Edge();//缺省构造函数
	Edge(int from, int to, int weight);//给定参数的构造函数
};
//**********一场过云雨**********

Graph.h

#pragma once
#include"Edge.cpp"
template<class T>
class Graph
{
public:
	static const int UNVISITED = 0;//未访问的顶点设置为0
	static const int VISITED = 1;//已访问的顶点设置为1
	int numVertex;//图中顶点的个数
	int numEdge;//图中边的条数
	int *Mark;//标记图的顶点是否被访问过
	int *Indegree;//存放图中顶点的入度
	Graph(int numVertex=1);//图的构造函数
	~Graph();//析构函数
	int VerticcesNum();//返回图的顶点个数
	int EdgesNum();//返回图的边数
	bool isEdge(Edge<T> oneEdge);//oneEdge是否为边
	void resetMark();//所有顶点设置成未访问状态
	int FromVertex(Edge<T> oneEdge);//返回oneEdge的起点	
	int ToVertex(Edge<T> oneEdge);//返回oneEdge的终点
	int Weight(Edge<T> oneEdge);//返回oneEdge的权
	virtual Edge<T> FirstEdge(int oneVertex) = 0;
	virtual Edge<T> NextEdge(Edge<T> preEdge) = 0;
	virtual void setEdge(int from, int to, int weight) = 0;
	virtual void delEdge(int from, int to) = 0;
};
//**********一场过云雨**********


Graphm.h

#pragma once
//#include"Edge.h"
#include"Graph.cpp"
template<class T>
class Graphm : public Graph<T>
{
private:
	int **matrix;
public:
	Graphm(int numVertex);
	~Graphm();
	Edge<T> FirstEdge(int oneVertex);
	Edge<T> NextEdge(Edge<T> preEdge);
	void setEdge(int from, int to, int weight);
	void delEdge(int from, int to);
	void IniGraphm(Graphm* Graphm, int* pWArray2D);
	void DFS(Graph<T>&G, int v);
	void BFS(Graph<T>&G, int v);
	void Visit(Graph<T>&G, int v);
	void Travel(Graph<T>&G, int startVertex = 0, int travelType = 0);
	void TravelByDFS(Graph<T>&G, int startVertex = 0);

};

//**********一场过云雨**********

源文件:

Edge.cpp

#include "Edge.h"
template<class T>
inline Edge<T>::Edge()
{
	from = -1;
	to = -1;
	weight = 0;
}

template<class T>
Edge<T>::Edge(int from, int to, int weight)
{
	this->from = from;
	this->to = to;
	this->weight = weight;
}
//**********一场过云雨**********

Graph.cpp

#include "Graph.h"
template<class T>
inline Graph<T>::Graph(int numVertex)
{
	this->numVertex = numVertex;
	this->numEdge = 0;
	this->Indegree = new int [numVertex];
	this->Mark = new int[numVertex];
	for (int i = 0; i < this->numVertex; i++) {
		this->Mark[i] = this->UNVISITED;
		this->Indegree[i] = 0;
	}
}

template<class T>
Graph<T>::~Graph()
{
	delete[]this->Mark;
	delete[]this->Indegree;
}

template<class T>
int Graph<T>::VerticcesNum()
{
	return numVertex;
}

template<class T>
int Graph<T>::EdgesNum()
{
	return numEdge;
}

template<class T>
bool Graph<T>::isEdge(Edge<T> oneEdge)
{
	if (oneEdge.weight > 0 && oneEdge.from >= 0 && oneEdge.to >= 0)
		return true;
	else return false;
}

template<class T>
void Graph<T>::resetMark()
{
	for (int i = 0; i < this->numVertex; i++) {
		this->Mark[i] = this->UNVISITED;
	}
}

template<class T>
int Graph<T>::FromVertex(Edge<T> oneEdge)
{
	return oneEdge.from;
}

template<class T>
int Graph<T>::ToVertex(Edge<T> oneEdge)
{
	return oneEdge.to;
}

template<class T>
int Graph<T>::Weight(Edge<T> oneEdge)
{
	return oneEdge.weight;
}
/*template<class T>
const int Graph<T>::UNVISITED = 0;
template<class T>
const int Graph<T>::VISITED = 1;*/
//**********一场过云雨**********

Graphm.cpp

#include "Graphm.h"
#include<iostream>
#include<queue>
using namespace std;
template<class T>
inline Graphm<T>::Graphm(int numVertex) :Graph<T>(numVertex)
{
	int i, j;
	this->matrix = (int **)new int *[numVertex];
	for (i = 0; i < numVertex; i++) {
		this->matrix[i] = new int[numVertex];
	}
	for (i = 0; i < numVertex; i++) {
		for (j = 0; j < this->numVertex; j++) {
			this->matrix[i][j] = 0;
		}
	}
}

template<class T>
Graphm<T>::~Graphm() 
{
	for (int i = 0; i < this->numVertex; i++) {
		delete[] matrix[i];
	}
	delete [] matrix;
}

template<class T>
Edge<T> Graphm<T>::FirstEdge(int oneVertex)
{
	Edge<T> myEdge;
	myEdge.from = oneVertex;
	for (int i = 0; i < this->numVertex; i++) {
		if (matrix[oneVertex][i] > 0) {
			myEdge.to = i;
			myEdge.weight = this->matrix[oneVertex][i];
			break;
		}
	}
	return myEdge;
}

template<class T>
Edge<T> Graphm<T>::NextEdge(Edge<T> preEdge)
{
	Edge<T> myEdge;
	myEdge.from = preEdge.from;
	if (preEdge.to < this->numVertex) {
		for (int i = preEdge.to + 1; i < this->numVertex; i++) {
			if (matrix[preEdge.from][i] > 0) {
				myEdge.to = i;
				myEdge.weight = matrix[preEdge.from][i];
				break;
			}
		}
	}
	return myEdge;
}

template<class T>
void Graphm<T>::setEdge(int from, int to, int weight)
{
	if (matrix[from][to] <= 0) {
		this->numEdge++;
		this->Indegree[to]++;
	}
	matrix[from][to] = weight;
}

template<class T>
void Graphm<T>::delEdge(int from, int to)
{
	if (matrix[from][to] > 0) {
		this->numEdge--;
		this->Indegree[to]--;
	}
	matrix[from][to] = 0;
}

template<class T>
void Graphm<T>::IniGraphm(Graphm * Graphm, int * pWArray2D)
{
	int N = this->numVertex;
	int array_i_j = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			array_i_j = *(pWArray2D + i * N + j);
			if (array_i_j > 0) 
				Graphm->setEdge(i, j, array_i_j);
			
		}
	}
}

template<class T>
void Graphm<T>::DFS(Graph<T>& G, int v)
{
	G.Mark[v] = Graphm<T>::VISITED;
	this->Visit(G, v);
	for (Edge<T> e = G.FirstEdge(v); G.isEdge(e); e = G.NextEdge(e)) {
		if (G.Mark[e.to] == Graphm<T>::UNVISITED)
			this->DFS(G, e.to);
	}
}

template<class T>
void Graphm<T>::BFS(Graph<T>& G, int v)
{
	using std::queue;
	queue<int> Q;
	this->Visit(G, v);
	G.Mark[v] =Graphm<T>::VISITED;
	Q.push(v);
	while (!Q.empty()) {
		int u = Q.front();
		Q.pop();
		for(Edge<T> e=G.FirstEdge(u);G.isEdge(e);e=G.NextEdge(e))
			if (G.Mark[e.to] == Graphm<T>::UNVISITED) {
				this->Visit(G, e.to);
				G.Mark[e.to] = Graphm<T>::VISITED;
				Q.push(e.to);
			}
	}
}

template<class T>
void Graphm<T>::Visit(Graph<T>& G, int v)
{
	cout << v <<"->";
}

template<class T>
void Graphm<T>::Travel(Graph<T>& G, int startVertex, int travelType)
{
	for (int i = startVertex, n = 0; n < this->numVertex; i++, n++) {
		i%=this->numVertex;
		if (Graphm<T>::UNVISITED == G.Mark[i]) {
			switch (travelType)
			{
			case 0:
				DFS(G, i);
				break;
			case 1:
				BFS(G, i);
				break;
			default:
				cout << "error" << endl;
				break;
	
			}
		}
	}
}

template<class T>
void Graphm<T>::TravelByDFS(Graph<T>& G, int startVertex)
{
	for (int i = startVertex, n = 0; n < this->numVertex; i++, n++) {
		i %= this->numVertex;
		if (Graphm<T>::UNVISITED == G.Mark[i]) {
			this->DFS(G, i);
		}
	}
}

//**********一场过云雨**********

DS07_02.cpp(主函数)

// DS07_02.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include"Graphm.cpp"
using namespace std;
int main()
{
	const int N = 7;
	int start1 = 0;
	int A[N][N] = {
			0,1,0,0,0,0,0,
			0,0,1,1,0,0,0,
			1,0,0,0,0,0,0,
			1,0,1,0,0,0,0,
			0,0,0,0,0,1,1,
			0,1,0,0,0,0,1,
			0,0,0,1,0,0,0,
	};
	
	Graphm<int> aGraphm(N);
	aGraphm.IniGraphm(&aGraphm, (int*)A);

	/*cout << "DFS:\t\t";
	aGraphm.DFS(aGraphm, start1);
	cout << endl;

	aGraphm.resetMark();
	cout << "BFS:\t\t";
	aGraphm.BFS(aGraphm, start1);
	cout << endl;*/

	aGraphm.resetMark();
	cout << "DFS Travel:\t";
	aGraphm.Travel(aGraphm, start1, 0);
	cout << endl;

	aGraphm.resetMark();
	cout << "BFS Travel:\t";
	aGraphm.Travel(aGraphm, start1, 1);
	cout << endl;
	return 0;
}
//**********一场过云雨**********

运行结果:

举报

相关推荐

0 条评论