图的遍历(深度优先遍历、广度优先遍历)

本文用于学习图的遍历(深度优先遍历、广度优先遍历)!!!

#include <iostream>

using namespace std;

typedef char VertexType;
typedef int EdgeType;

const int MAXSIZE = 100;
bool visited[MAXSIZE];

typedef int QElemType;
typedef struct
{
	QElemType data[MAXSIZE];
	int front;//头指针
	int rear;//尾指针
}SqQueue;//定义循环队列顺序存储类型
void InitQueue(SqQueue &q)//队列初始化
{
	q.front = 0;
	q.rear = 0;
}
void EnQueue(SqQueue &q, QElemType &e)//入队列,将元素插入循环队列的队尾
{
	q.data[q.rear] = e;
	q.rear = (q.rear + 1) % MAXSIZE;
}
void DeQueue(SqQueue &q, QElemType &e)//出队列,头指针后移
{
	e = q.front;
	q.front = (q.front) % MAXSIZE;
}
bool QueueEmpty(SqQueue &q)//判断队列是否为空,头指针等于尾指针
{
	if (q.front == q.rear)
		return true;
}
typedef struct//定义邻接矩阵类型
{
	int numVertexes, numEdges;
	VertexType vertex[MAXSIZE];//顶点数组
	EdgeType arc[MAXSIZE][MAXSIZE];//边数组
}MGraph;

void createMGraph(MGraph *G)//创建邻接矩阵存储无向图
{
	cout << "输入顶点数量和边数量:";
	cin >> G->numVertexes >> G->numEdges;
	cout << "输入顶点信息:";
	for (int i = 0; i < G->numVertexes; i++)
		cin >> G->vertex[i];
	for (int i = 0; i < G->numVertexes; i++)//邻接表初始化
		for (int j = 0; j < G->numVertexes; j++)
			G->arc[i][j] = false;
	cout << "输入边(下标,下标):" << endl;
	for (int i = 0; i < G->numEdges; i++)
	{
		int a, b;
		cin >> a >> b;
		G->arc[a][b] = true;
		G->arc[b][a] = G->arc[a][b];//无向图是对称矩阵
	}
}
void DFS(MGraph *g, int i)
{
	visited[i] = true;
	cout << "访问的顶点:" << g->vertex[i] << endl;
	for (int j = 0; j < g->numVertexes; j++)
	{
		if (g->arc[i][j] == 1 && !visited[i])//遍历每行
			DFS(g, j);//未访问的顶点递归操作
	}
}
void DFSTraverse(MGraph *g)//深度优先遍历,类似树的前序遍历
{
	for (int i = 0; i < g->numVertexes; i++)//访问标志数组初始化
		visited[i] = false;
	for (int i = 0; i < g->numVertexes; i++)
	{
		if (!visited[i])
			DFS(g, i);
		cout << "test!!!" << endl;
	}

}
void BFSTraverse(MGraph *g)//广度优先遍历,类似树的层序遍历
{
	int i, j;
	SqQueue q = {};
	InitQueue(q);
	for (i = 0; i < g->numVertexes; i++)//初始化访问标志数组
		visited[i] = false;
	for (i = 0; i < g->numVertexes; i++)//遍历每个顶点
	{
		if (!visited[i])
		{
			visited[i] = true;
			cout << "当前访问的顶点:" << g->vertex[i] << endl;
			EnQueue(q, i);//此顶点入队列
			while (!QueueEmpty(q))
			{
				DeQueue(q, i);//队首元素出队列
				for (j = 0; j < g->numVertexes; j++)//遍历与出队列元素连接的所有顶点
				{
					if (g->arc[i][j] == 1 && !visited[j])
					{
						visited[j] = true;
						cout << "当前访问的顶点:" << g->vertex[i] << endl;
						EnQueue(q, j);//此顶点入队列,队列中的元素都是已经访问过的
					}
				}
			}
		}
	}
}


typedef struct EdgeNode//定义边表结点类型
{
	EdgeType weight;//权重
	int adjVex;//邻接结点
	struct EdgeNode *next;//指向下一个结点
}EdgeNode;
typedef struct VertexNode//定义顶点结点类型
{
	VertexType data;//顶点信息
	EdgeNode *firstEdge;//指向边表的头一结点
}VertexNode,AdjList[MAXSIZE];
typedef struct//定义邻接链表类型
{
	int numVertexes, numEdges;
	AdjList adjList;
}GraphAdjList;//直接创建结构体变量
void createGraphAdjList(GraphAdjList *G)//创建邻接表存储无向图
{
	cout << "输入顶点数量和边数量:";
	cin >> G->numVertexes >> G->numEdges;
	cout << "输入顶点信息:";
	for (int i = 0; i < G->numVertexes; i++)//存储顶点表结点信息
	{
		cin >> G->adjList[i].data;
		G->adjList[i].firstEdge = NULL;
	}
	EdgeNode *e;
	for (int k = 0; k < G->numEdges; k++)//头插法,存储边表结点信息
	{
		int i, j;
		cout << "输入边(下标,下标):" << endl;
		cin >> i >> j;
		e = (EdgeNode *)malloc(sizeof(EdgeNode));
		e->adjVex = j;//存储邻接点j
		e->next = G->adjList[i].firstEdge;//将e结点插入到顶点表指向的头结点前面
		G->adjList[i].firstEdge = e;//将顶点表结点指向e结点

		e = (EdgeNode *)malloc(sizeof(EdgeNode));//无向图,反向操作
		e->adjVex = i;
		e->next = G->adjList[j].firstEdge;
		G->adjList[j].firstEdge = e;
	}
}
void DFS(GraphAdjList *gl, int i)
{
	EdgeNode *p;
	visited[i] = true;
	cout << "当前访问的结点:" << gl->adjList[i].data << endl;
	p = gl->adjList[i].firstEdge;//获得邻接边表结点
	while (p)
	{
		if (!visited[p->adjVex])
			DFS(gl, p->adjVex);//未访问的顶点递归操作
		p = p->next;
	}
}
void DFSTraverse(GraphAdjList *gl)
{
	for (int i = 0; i < gl->numVertexes; i++)
		visited[i] = false;
	for (int i = 0; i < gl->numVertexes; i++)
	{
		if (!visited[i])//连通图仅调用DFS函数一次
			DFS(gl, i);
		cout << "test!!!" << endl;
	}
}
void BFSTraverse(GraphAdjList *gl)
{
	int i;
	for (i = 0; i < gl->numVertexes; gl++)
		visited[i] = false;
	SqQueue q = {};
	InitQueue(q);
	EdgeNode *p;
	for (i = 0; i < gl->numVertexes; gl++)
	{
		if (!visited[i])
		{
			visited[i] = true;
			cout << "当前访问的顶点:" << gl->adjList[i].data << endl;
			EnQueue(q, i);
			if (!QueueEmpty(q))
			{
				DeQueue(q, i);
				p = gl->adjList[i].firstEdge;
				while (p)
				{
					if (!visited[p->adjVex])
					{
						visited[p->adjVex] = true;
						cout << "当前访问的顶点:" << gl->adjList[p->adjVex].data << endl;
						EnQueue(q, p->adjVex);
					}
					p = p->next;
				}
			}
		}
	}
}


int main(int *argc, int **argv)
{
	MGraph G = {};
	MGraph *g;
	g = &G;
	createMGraph(g);
	for (int i = 0; i < g->numVertexes; i++)
	{
		for (int j = 0; j < g->numVertexes; j++)
		{
			cout << g->arc[i][j] << " ";//打印邻接表信息
		}
		cout << endl;
	}
	DFSTraverse(g);
	BFSTraverse(g);

	GraphAdjList GL = {};
	GraphAdjList *gl;
	gl = &GL;
	createGraphAdjList(gl);
	EdgeNode *p;
	for (int i = 0; i < gl->numVertexes; i++)
	{
		cout << "顶点:" << gl->adjList[i].data << " ";
		p = gl->adjList[i].firstEdge;
		while (p)
		{
			cout << "边表结点:" << p->adjVex << " ";
			p = p->next;
		}
		cout << endl;
	}
	DFSTraverse(gl);
	BFSTraverse(gl);
	return 0;
}

参考资料:

1.《大话数据结构》


猜你喜欢

转载自blog.csdn.net/attitude_yu/article/details/80161803