图 - 用邻接表存储一个自定义的图,输出DFS和BFS序列(C++)

涉及的知识点:

1. 邻接表的建立。
2. Breadth First Search:广度优先搜索,利用队列,使用类似于二叉树层次遍历的方法,将顶点V出队后将V的邻接点入队,重复上述过程,直至访问完所有的节点(队列为空)。
3.Depth First Search: 深度优先搜索,从顶点V出发一路走到黑,走不下去的时候利用回溯的思想原路返回,直到从起点V出发并且利用回溯法又一次回到了起点时,搜索完成。(递归实现)。

本题输入所对应的图:


话不多说,直接上代码:

//#pragma once

/* 图的邻接表表示法 */
//DFS、BFS

#include <iostream>
#include <malloc.h> 
using namespace std;

#define MaxVertexNum 50    /* 最大顶点数设为50 */
typedef int Vertex;         /* 用顶点下标表示顶点,为整型 */
typedef int WeightType;        /* 边的权值设为整型 */
typedef char DataType;        /* 顶点存储的数据类型设为字符型 */

int Visited[MaxVertexNum];   //全局变量,用来表示节点是否被访问 

typedef struct arcnode  //边结构
{
	int adjvex;  //下一条边的始点编号
	struct arcnode* nextarc;  //下一条边的指针
};

typedef struct vexnode  //顶点数组
{
	Vertex vertex;  //顶点编号
	arcnode* firstarc;  //边表头指针
}AdjList[MaxVertexNum];

//LGraph类定义 - 邻接表类定义--------
template <class T>
class LGraph
{
	private:
		int Nv;  //顶点数
		int Ne;  //边数
		AdjList adjlist;  //邻接表所表示的图(指针数组)

	public:
		LGraph() { Nv = 0; Ne = 0; }  //构造函数
		~LGraph();  //析构函数
		bool BuildLGraph();  //根据用户输入建立一个图
		void DFS(Vertex v);  //从顶点v开始深度优先搜索
		void BFS(Vertex v);  //从顶点v开始广度优先搜索
		void DispLGraph();   //输出由邻接表所表示的图
		int GetNv() { return Nv; }  //获取顶点数 
};


//LGraph类的实现
template <class T>
bool LGraph<T>::BuildLGraph()
{
	int i, k, j;
	arcnode *p = NULL;

	cout << "--------创建一个由邻接表所表示的图---------" << endl;
	cout << "顶点数:";
	cin >> Nv;
	cout << "边数:";
	cin >> Ne;

	//初始化邻接表
	for (i = 0; i < Nv; i++)
	{
		adjlist[i].vertex = i;
		adjlist[i].firstarc = NULL;
	}
	for (k = 0; k < Ne; k++)
	{
		cout << "  第" << k + 1 << "条边(节点号从0到" << Nv - 1 << "):";
		cin >> i >> j;
		p = new arcnode;  //创建边节点
		//初始化边节点
		p->adjvex = j;
		p->nextarc = NULL;
		//将边节点p插入到adjlist[i]链表的前面
		p->nextarc = adjlist[i].firstarc;
		adjlist[i].firstarc = p;
	}
}

//DispLGraph() - 输出由邻接表所表示的图
template <class T>
void LGraph<T>::DispLGraph()
{
	cout << "------输出一个由邻接表所表示的图--------" << endl;
	int i, have;  //have用来标记顶点V是否有邻接点
	arcnode *p = NULL;

	for (i = 0; i < Nv; i++)
	{
		p = adjlist[i].firstarc;
		have = 0;
		while (p != NULL)
		{
			cout << "  (" << i << ", " << p->adjvex << ")";
			p = p->nextarc;
			have = 1;
		}

		if (have == 1)
			cout << endl;
	}
}

//~LGraph() - 析构函数
template <class T>
LGraph<T>::~LGraph()
{
	cout << "--------释放动态分配的存储空间----------" << endl;
	int i;
	arcnode *p = NULL, *tmp = NULL;
	
	for (i = 0; i < Nv; i++)
	{
		p = adjlist[i].firstarc;
		while (p != NULL)
		{
			tmp = p;
			p = p->nextarc;
			delete tmp;
		}
	}
}

//DFS(Vertex v) - 从顶点v开始深度优先搜索图g(回溯思想)
template <class T>
void LGraph<T>::DFS(Vertex v)
{
	arcnode *p = NULL;
	cout << v << " ";  //访问节点v
	Visited[v] = 1;  //标记v节点已被访问
	p = adjlist[v].firstarc;  //p指向节点v的表头指针

	while (p != NULL)
	{
		if (!Visited[p->adjvex])  //若v有邻接点
			DFS(p->adjvex);  //递归调用DFS
		p = p->nextarc;
	}
}

//BFS(Vertex v) - 从顶点v开始广度优先搜索图g(类似于树中的层次遍历) - 使用队列
template <class T>
void LGraph<T>::BFS(Vertex v)
{
	//定义队列
	int queue[MaxVertexNum], rear = 0, first = 0;  //rear - 队尾、first - 队头指针
	
	int i;
	arcnode *p = NULL;
	//将节点标记清0
	for (i = 0; i < Nv; i++)
		Visited[i] = 0;
	
	cout << v << " ";  //访问节点v
	Visited[v] = 1;  //标记节点v入队 
	queue[++rear] = v;  //v入队列

	while (rear != first)  //队列不为空时
	{
		v = queue[++first];  //队头节点出队
		p = adjlist[v].firstarc;  //找到队头节点所对应的表头指针
		while (p != NULL)
		{
			if (!Visited[p->adjvex])  //若队头节点有邻接点,则再以邻接点为起点去找到该邻接点所对应的链表
			{
				cout << p->adjvex << " ";  //访问p
				Visited[p->adjvex] = 1;  //添加标记
				queue[++rear] = p->adjvex;  //p入队
			}

			p = p->nextarc;
		}
	}
}

void InitVisited(int num)
{
	int i;
	//节点标记清0
	for (i = 0; i < num; i++)
		Visited[i] = 0;
}

int main()
{
	LGraph<int> lgraph;
	Vertex v;  //指定的访问起点 
	
	lgraph.BuildLGraph();  //建立邻接表形式表示的图 
	lgraph.DispLGraph();  //输出该图 
	
	cout << "访问起点:";
	cin >> v; 
	
	//BFS - Breadth First Search 
	cout << "BFS: ";
	int num = lgraph.GetNv();  //取得节点数 
	InitVisited(num);  //访问标记清0 
	lgraph.BFS(v);  
	cout << endl;
	
	//DFS - Depth First Search 
	cout << "DFS:"; 
	InitVisited(num);
	lgraph.DFS(v);
	cout << endl;
	
	return 0;
}

输入与输出:


猜你喜欢

转载自blog.csdn.net/y_16041527/article/details/80371611