数据结构——邻接矩阵的深度优先遍历(DFS)和广度优先遍历(BFS)的理解和实现

数据结构——图的邻接矩阵实现
深度优先遍历
**第一步:**构造一个访问数组,大小和顶点数目一样多 初始化都记为0 意为没有访问过
第二步从第一个顶点或者最后一个顶点为起点 判断该顶点有没有走过 再进行DFS函数 最后依次走后面每个顶点(用访问数组判断是否走过)
第三步构造 DFS函数 :
DFS函数 就是从某一顶点开始 根据边是否存在为判断 走次边 然后将其边的另一顶点记为1(走过)

前期准备

typedef int Boolean;//深度遍历的数组为布尔类型 用来标记
Boolean visited[MAXVER];//深度遍历的访问数组

执行部分

/*邻接矩阵的深度遍历算法   访问数组初始化,对每个顶点都可以走一遍  前提是没有走过的*/

Status DFS(MGhaph &G, int i)
{
    
    
	int j;
	visited[i] = true;
	cout << "此时访问的顶点为: "<< endl;
	cout << G.vexs[i]<< endl;
	for (j = 0; j < G.numver; j++)
	{
    
    
		if (G.arc[j][i] != INF && !visited[j])//递归之处   从i为开始 又转到从j的0到顶点数都寻找一遍
			DFS(G,j);
	}
	return 0;
}

Status DFSTraverse(MGhaph &G)
{
    
    
	int i;
	for (i = 0; i < G.numver; i++)//访问数组都记为0  意为 顶点没有被访问过
	{
    
    
		visited[i] = false;
	}

	for (i = 0; i < G.numver; i++)
	{
    
    
		if (!visited[i])//所有顶点都可以访问(前提是:之前没有被访问过) 且从该顶点开始循环
		{
    
    
			cout << "从" << i << "开始访问" << endl;
			DFS(G, i);
		}
		
	}
	return 0;
}

/*————————深度优先遍历————————*/


思考:深度优先遍历 能够走每一个顶点 且不重复,可以对顶点做一些操作(当然也可以重复 但是复杂度就高了) 属于搜索类的算法吧


广度优先遍历涉及到一个队列

先定义一个队列queue.h

#include<iostream>
//#include <iomanip>
using namespace std;
typedef char elementtype;
typedef int Status;

typedef struct QNode
{
    
    
	char data;
	struct QNode *next;
}QNode, *Queueptr;

typedef struct Queue
{
    
    
	QNode *head;
	QNode *tail;
}Queue;

//初始化队列
Status InitQueue(Queue &Q)
{
    
    
	Q.head = Q.tail = (Queueptr)malloc(sizeof(QNode));
	Q.head->next = NULL;
	Q.tail->next = NULL;
	return 0;
}
//头指针和尾指针只有一个
//插入元素
Status Enqueue(Queue &Q, elementtype x)
{
    
    
	Queueptr p = (Queueptr)malloc(sizeof(QNode));//创建一个结点

	p->data = x;
	p->next = NULL;
	Q.tail->next = p;
	Q.tail = p;
	return 0;
}

Status Dequeue(Queue &Q, elementtype &y)
{
    
    
	if (Q.head == Q.tail)
	{
    
    
		return NULL;

	}

	Queueptr q;
	q = Q.head->next;
	y = q->data;

	Q.head->next = q->next;
	if (Q.tail == q)
	{
    
    
		Q.tail = Q.head;
	}
	free(q);
	return 0;
}

Status QueueEmpty(Queue &Q)
{
    
    
	if (Q.head != NULL || Q.tail != NULL)
	{
    
    
		return 1;
	}
	else
		return 0;
}



再在数据结构——图的邻接矩阵实现加上这个
同时#include"queue.h"即可

/*————————实现广度优先遍历————————*/

void BFS(MGhaph &G)
{
    
    
	char x;
	int i, j;
	Queue Q;
	for (i = 0; i < G.numver; i++)
	{
    
    
		visited[i] = false;//标记
	}
	InitQueue(Q);//初始化队列

	for (i = 0; i < G.numver; i++)
	{
    
    
		if (!visited[i])//如果从未访问过
		{
    
    
			visited[i] = true;//标记 走过的顶点 并输出,并将此顶点存入队列
			cout << "此时访问的顶点为: " << endl;
			cout << G.vexs[i] << endl;
			Enqueue(Q, G.vexs[i]);//将此顶点进入队列


			while (!QueueEmpty(Q))//若此时队列不为空时  进入   空时弹出
			{
    
    
				Dequeue(Q,x);//把队列里的一个元素弹出

				for (j = 0; j < G.numver; j++)
				{
    
    
					if (G.arc[j][i] != INF && !visited[j])//寻找和i所在的元素有弧的元素
					{
    
    
						visited[j] = true;//标记走过
						cout << "从" << j << "开始访问" << endl;
						cout <<G.vexs[j] << endl;
						Enqueue(Q, G.vexs[j]);//将有联系的顶点元素入队列
					}
				}
			}
		}
	}
}

广义优先遍历:
1.构造一个队列来存储顶点元素 作为一个中间过程
2.构造一个访问数组 来标记被访问过的顶点
3.设置一个for循环 每次访问的顶点将其存入队列中
再进入while循环(判断队列是否为空 )不为空时进入循环体

弹出队里一个元素

进入for循环 寻找 和该顶点相关的边的顶点
找到相关边顶点之后 存入队列,标记访问过

for循环结束后 还是在while循环里 此时,将队列清空才能跳出
意在大循环里 的队列回到初始化

猜你喜欢

转载自blog.csdn.net/weixin_46096297/article/details/113435033