#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;
}
模板_图
最新推荐文章于 2021-12-24 20:19:15 发布