模板_图

#include<iostream>
#include<queue>
#include<stack>
using namespace std;

template<class numtype>class Graph;	//图类的声明

template<class numtype>
class AdjVNode	//邻接点类的定义
{
	public:
		AdjVNode(int num):index_value(num), next(NULL){}
		friend class Graph<numtype>;	//声明邻接点类是图类的友元类
	private:
		int index_value;	//该结点元素在顶点表中的下标
		AdjVNode<numtype>* next;	//指向下一结点
};

template<class numtype>
class Graph	//图类的定义
{
	public:
		Graph(int number_vertex, int number_edge, int max_size = 50);
		~Graph();
		bool AddVertex(numtype vertex);	//增加结点
		bool AddEdge(numtype vertex1, numtype vertex2);	//增加边
		bool DFS();	//DFS
		bool BFS ();	//BFS

	private:
		typedef struct vnode{	//顶点表头结点的定义
			AdjVNode<numtype>* FirstEdge;	//边表头指针
			numtype vertex;	//结点元素
		}Vnode;	//邻接表类型
			
		int Now_VertexSum;	//已存储顶点数
		int Now_EdgeSum;	//已存储边数
		int MaxVertexNum;	//最大顶点数
		int Nv;	//顶点数
		int Ne;	//边数
		Vnode* G;	//邻接表
		bool* Visited;	//顶点的访问标记

		bool InitGraph(int number_vertex, int number_edge);	// 初始化图
		bool ReSet();	//重置访问标记
		int Count(numtype vertex);	//计算结点所处的下标
		bool Visit(int vertex_index_value);	//输出结点元素
		bool _DFS(int vertex_index_value);	//深度优先遍历
		bool _BFS ();	//广度优先遍历
		bool Delete_All_Vertexs();	//删除所有结点
		bool Delete_Edge(int vertex_index_value);	//删除一条顶点所出的所有边
		bool Delete_All_Edges();	//删除所有边
};

int main()
{
	Graph<char> temp_char(6, 7);
	for (int i = 0; i < 6; i++)
	{
		temp_char.AddVertex('a' + i);
	}
	temp_char.AddEdge('a', 'b');
	temp_char.AddEdge('a', 'c');
	temp_char.AddEdge('a', 'f');
	temp_char.AddEdge('b', 'd');
	temp_char.AddEdge('b', 'e');
	temp_char.AddEdge('e', 'c');
	temp_char.AddEdge('d', 'e');
	temp_char.DFS();
	temp_char.BFS();
	cout << endl << endl;

	Graph<int> temp_int(6, 7);
	for (int i = 0; i < 6; i++)
	{
		temp_int.AddVertex(i);
	}
	temp_int.AddEdge(0, 1);
	temp_int.AddEdge(0, 2);
	temp_int.AddEdge(0, 5);
	temp_int.AddEdge(1, 3);
	temp_int.AddEdge(1, 4);
	temp_int.AddEdge(4, 2);
	temp_int.AddEdge(3, 4);
	temp_int.DFS();
	temp_int.BFS();
	cout << endl << endl;

	Graph<double> temp_double(6, 7);
	for (int i = 0; i < 6; i++)
	{
		temp_double.AddVertex(i * 1.987654);
	}
	temp_double.AddEdge(0 * 1.987654, 1 * 1.987654);
	temp_double.AddEdge(0 * 1.987654, 2 * 1.987654);
	temp_double.AddEdge(0 * 1.987654, 5 * 1.987654);
	temp_double.AddEdge(1 * 1.987654, 3 * 1.987654);
	temp_double.AddEdge(1 * 1.987654, 4 * 1.987654);
	temp_double.AddEdge(4 * 1.987654, 2 * 1.987654);
	temp_double.AddEdge(3 * 1.987654, 4 * 1.987654);
	temp_double.DFS();
	temp_double.BFS();

	return 0;
}


template<class numtype>
Graph<numtype>::Graph(int number_vertex, int number_edge, int max_size = 50)
{
	MaxVertexNum = max_size;
	G = new Vnode[MaxVertexNum];
	Visited = new bool[MaxVertexNum];
	InitGraph(number_vertex, number_edge);
}

template<class numtype>
Graph<numtype>::~Graph()
{
	Delete_All_Vertexs();
	Delete_All_Edges();
	delete G;
	G = NULL;
	delete Visited;
	Visited = NULL;
}

template<class numtype>
bool Graph<numtype>::InitGraph(int number_vertex, int number_edge)
{
	Nv = number_vertex;
	Ne = number_edge;
	Now_VertexSum = 0;
	Now_EdgeSum = 0;

	for (int i = 0; i < number_vertex; i++){
		Visited[i] = false;
		G[i].FirstEdge = NULL;
		G[i].vertex = NULL;
	}

	return true;
}

template<class numtype>
bool Graph<numtype>::Delete_All_Vertexs()	//删除所有结点
{
	for (int i = Now_VertexSum - 1; i >= 0; i--)
	{
		G[i].vertex = NULL;
		Now_VertexSum--;
	}
	return true;
}

template<class numtype>
bool Graph<numtype>::Delete_Edge(int vertex_index_value)	//删除一条顶点所出的所有边
{
	if (G[vertex_index_value].FirstEdge == NULL){
		return true;
	}
	else{
		AdjVNode<numtype>* temp_node = G[Count(vertex_index_value)].FirstEdge;
		stack<AdjVNode<numtype>*> stack;
		while (temp_node != NULL)
		{
			stack.push(temp_node);
			temp_node = temp_node->next;
		}
		while (stack.empty() != true)
		{
			temp_node = stack.top();
			stack.pop();
			delete temp_node;
			temp_node = NULL;
			Now_EdgeSum--;
		}
	}
	return true;
}

template<class numtype>
bool Graph<numtype>::Delete_All_Edges()	//删除所有边
{
	for (int i = Now_VertexSum - 1; i > 0; i--)
	{
		Delete_Edge(i);
	}
	return true;
}

template<class numtype>
bool Graph<numtype>::AddVertex(numtype vertex)	//增加结点
{
	if (Now_VertexSum == Nv){
		cerr << "顶点已满, 增加结点失败!!!" << endl;
		exit(1);
	}
	G[Now_VertexSum].vertex = vertex;
	Now_VertexSum++;
	return true;
}

template<class numtype>
bool Graph<numtype>::AddEdge(numtype vertex1, numtype vertex2)	//增加边
{
	if (Now_EdgeSum == Ne){
		cerr << "边已满, 增加边失败!!!" << endl;
		exit(1);
	}
	AdjVNode<numtype>* vertex_node = new AdjVNode<numtype>(Count(vertex2));
	vertex_node->next = NULL;
	
	if (G[Count(vertex1)].FirstEdge == NULL){
		G[Count(vertex1)].FirstEdge = vertex_node;
	}
	else{
		AdjVNode<numtype>* temp_node = G[Count(vertex1)].FirstEdge;
		while (temp_node->next != NULL)
		{
			temp_node = temp_node->next;
		}
		temp_node->next = vertex_node;
	}
	Now_EdgeSum++;
	return true;
}

template<class numtype>
bool Graph<numtype>::DFS()
{
	ReSet();
	cout << "DFS from ";
	Visit(0);
	cout << ":   ";
	_DFS(0);
	putchar('\n');
	return true;
}

template<class numtype>
bool Graph<numtype>::_DFS(int vertex_index_value)	//Graph表示邻接矩阵存储的图,V表示当前访问的节点。第三个参数为输出节点的函数
{
	Visit(vertex_index_value);	//访问到V,输出
	Visited[vertex_index_value] = true;	//标记V被访问过,此后不再访问

	for(AdjVNode<numtype>* temp_node = G[vertex_index_value].FirstEdge; temp_node != NULL; temp_node = temp_node->next)
	{	//数据是0到Graph->Nv(顶点数点数),访问每个节点
		if(Visited[temp_node->index_value] == false){	//如果w没有被访问过
			_DFS(temp_node->index_value);	//从temp_node开始搜索访问
		}
	}
	return true;
}

template<class numtype>
bool Graph<numtype>::BFS()
{
	ReSet();
	cout << "BFS from ";
	Visit(0);
	cout << ":   ";
	_BFS();
	putchar('\n');
	return true;
}

template<class numtype>
bool Graph<numtype>::_BFS ()//Graph表示邻接矩阵存储的图,V表示当前访问的节点。第三个参数为输出节点的函数
{
	queue<int> queue;
	queue.push(0);//队列存入访问的第一个节点
    Visited[0] = true;//标记S被访问过,以后不再访问

	while(queue.empty() != true)
	{//当队列不为空时
		int pos = queue.front();//取出队首元素
		queue.pop();	//删除队首元素
	    Visit(pos);//输出取出的节点
        
		for(AdjVNode<numtype>* temp_node = G[pos].FirstEdge; temp_node != NULL; temp_node = temp_node->next)
		{//依次访问与pos相连的节点
			if(Visited[temp_node->index_value] == false){//如果这个节点没有被访问过
	        	Visited[temp_node->index_value] = true;//标记这个节点被访问
				queue.push(temp_node->index_value);//把这个节点加入到队列中
			}
		}
	}
	return true;
}

template<class numtype>
int Graph<numtype>::Count(numtype vertex)
{
	for (int i = 0; i < Nv; i++)
		if (vertex == G[i].vertex)
			return i;
	return -1;
}

template<class numtype>
bool Graph<numtype>::Visit(int vertex_index_value)
{
	cout << G[vertex_index_value].vertex << ' ';
	return true;
}

template<class numtype>
bool Graph<numtype>::ReSet()
{
	for (int i = 0; i < Ne; i++){
		Visited[i] = false;
	}
	return true;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值