データ構造-隣接行列の深さ優先走査(DFS)と幅優先探索(BFS)の理解と実装

データ構造-グラフの隣接行列は
深さ優先走査を実装します
**最初のステップ:**頂点の数と同じサイズのアクセス配列を構築します。初期化は0として記録されます。これは、
2番目のステップがアクセスされていないことを意味します。最初の頂点または最後の頂点から、頂点が通過したかどうかを判断するための開始点であり、DFS機能を実行します。最後に、各頂点を順番にたどります(アクセス配列を使用して通過したかどうかを判断します)
。3番目のステップDFS関数作成することです。DFS関数
は、エッジが存在するかどうかに応じて特定の頂点から開始します。2番目のエッジを判断し、そのエッジのもう一方の頂点を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ループ設定しますそして
、それが空でない場合にループ(キューが空であるかどうかを決定する)ループ本体を入力しながら入力

チーム内の要素をポップアップします

forループに入り、頂点に
関連するエッジの頂点を見つけます。関連するエッジの頂点を見つけたら、それをキューに保存し、訪問済みをマークします。

forループが終了した後も、whileループ内にあります。この時点で、キューをクリア
して、大きなループのキューからジャンプし、初期化に戻ります。

おすすめ

転載: blog.csdn.net/weixin_46096297/article/details/113435033