有向图的构建以及遍历(包括邻接矩阵以及图的基本函数)

#include<stack>
#include<queue>
#include"Edge.h"
#define VISITED 1       //已经访问过
#define UNVISITED 0     //未访问过
#define AFFINITY 999999 //最大值
using namespace std;

template<class EdgeType>         //边的类,包括有向图的边的起始点,终点以及权值
class Edge {
public:
	int start, end;
	EdgeType weight;
	Edge();

	Edge(int st = -1, int en = -1, int w = -1) {
		start = st;
		end = en;
		weight = w;
	}
	bool operator > (Edge oneEdge);//重载>
	bool operator < (Edge oneEdge);//重载<      //重载函数只给出声明

};




//图的类
template<class EdgeType>
class Graph
{
public:
	int vertexNum;//顶点个数
	int edgeNum;  //表示边的个数
	int* Mark;    //用进行图的各种算法的辅助数组,并无实际意义
	int** matrix; //指向邻接矩阵的指针
	Graph(int verticesNum) {//构造函数(包括邻接矩阵的初始化
		int i, j;
		vertexNum = verticesNum;
		edgeNum = 0;
		Mark = new int[vertexNum];
		for (int i = 0; i < vertexNum; i++) {
			Mark[i] = UNVISITED;
		}
		matrix = (int**)new int*[vertexNum];
		for (i = 0; i < vertexNum; i++) {
			matrix[i] = new int[vertexNum];
		}
		for(i = 0;i<vertexNum;i++)
			for (j = 0; i < vertexNum; j++) {
				matrix[i][j] = 0;
			}
	}
	~Graph() {              //图的析构函数,包括析构辅助数组、邻接矩阵
		delete[]Mark;
		for (int i = 0; i < vertexNum; i++)
			delete matrix[i];
		delete matrix;
	}
	Edge<EdgeType> FirstEdge(int oneVertex) {//返回该顶点的第一条边,图的基本函数,为图的算法做准备
		Edge<EdgeType> tmpEdge;
		tmpEdge.start = oneVertex;
		for (int i = 0; i < vertexNum; i++) {//找邻接矩阵当前行不为0的第一个值也就是第一条边
			if (matrix[oneVertex][i] != 0) {
				tmpEdge.end = i;
				tmpEdge.weight = matrix[oneVertex][i];
				break;
			}
		}
		return tmpEdge;
	}
	Edge<EdgeType> NextEdge(Edge<EdgeType> oneEdge) {//返回与oneEdge有相同始点的下一条边
		Edge<EdgeType> tmpEdge;
		tmpEdge.start = oneEdge.start;
		for (int i = oneEdge.end + 1; i < vertexNum; i++) {
			if (matrix[oneEdge.start][i] != 0) {
				tmpEdge.end = i;
				tmpEdge.weight = matrix[oneEdge.start][i];
				break;
			}
		}
		return tmpEdge;
	}
	void setEdge(int start, int end,EdgeType weight = 0) {//新增一条边
		if (matrix[start][end] == 0) {
			edgeNum++;
		}
		matrix[start][end] = weight;
	}
	void delEdge(int start, int end) {                //删除一条已经存在的边
		if (matrix[start][end] != 0) {
			edgeNum--;
		}
		matrix[start][end] = 0;
	};
	int VerticesNum() {                                //返回结点的数目
		return vertexNum;
	}
	int EdgeNum() {                                 //返回边的数目
		return edgeNum;
	}
	bool IsEdge(Edge<EdgeType> oneEdge ) {           //检测是否是当前图中的一个边
		if (oneEdge.weight > 0)
			return true;//如果是边,则就返回true
		else
			return false;
	}
	int StartVertex(Edge<EdgeType> oneEdge) {//返回始点
		return oneEdge.start;
	}
	int EndVertex(Edge<EdgeType> oneEdge) {//返回结束点
		return oneEdge.end;
	}
	int WeightVertex(Edge<EdgeType> oneEdge) {//返回边的权
		return oneEdge.weight;
	}
    void DfsReverse();		//深度优先搜索递归
	void DfsNoReverse();	//深度优先搜索非递归
	void BfsNoReverse(int v);//广度优先搜索非递归
}

template<class EdgeType>
void Graph<EdgeType>::DfsReverse() {//递归的深度优先搜索算法
	for (int i = 0; i < VerticesNum(); i++)
		Mark[i] = UNVISITED;
	for (int i = 0; i < VerticesNum; i++) {
		if (Mark[i] == UNVISITED) {//检查图中是否有为未访问的结点,
			DfsReverse(i);			//如果有则从当前节点开始深度优先搜索
		}
	}
}
template<class EdgeType>
void Graph<EdgeType>::DfsNoReverse() {//深度优先搜索
	int i, v, u;
	stack <int> s;
	
	for (i = 0; i < VerticesNum(); i++)
		Mark[i] = UNVISITED;
	for (i = 0; i < VerticesNum(); i++) {
		if (Mark[i] == UNVISITED) {
			s.push(i);
//			visit(i);				//访问方式未定
			Mark[i] = VISITED;
			while (!s.empty()) {
				v = s.pop();
				for (Edge<EdgeType> e = FirstEdge(v); IsEdge(e); e = NextEdge(e)) {
					u = EndVertex(e);
					if (Mark[u] == UNVISITED) {
						s.push(u);
//						visit(i);
						Mark[u] = VISITED;
					}
				}
			}
		}
	}
}
template<class EdgeType>
void Graph<EdgeType>::BfsNoReverse(int v) {
	for (int i = 0; i < VerticesNum(); i++)
		Mark[i] = UNVISITED;
	queue<EdgeType> q;
	Mark[v] = VISITED;
//	visit(v);
	q.push(v);
	while (!q.empty()) {
		v = q.front();
		q.pop();
		for (Edge<EdgeType> e = FirstEdge(v); IsEdge(v); e = NextEdge(e)) {
			int u = EndVertex(e);
			if (Mark[u] == UNVISITED) {
				Mark[u]=VISITED;
//				visit(EndVertex(e));
				q.push(u);
			}
		}
	}
}

在代码段中,展示了有向图的基本操作以及邻接矩阵的构造,邻接矩阵就是一个n*n的二维数组,用以储存边的信息。图的遍历包括广度优先搜索的非递归以及深度优先搜索的递归算法和非递归算法,在本类中也运用了多个辅助函数,譬如FirstEdge()、NextEdge()以及其他为了封装性而创建的函数。图的操作和树的操作具有很强的类似性。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值