04グラフトラバーサル - 問題のグラフの頂点を見つけます

図BFSの幅優先トラバーサル

また、幅優先探索アルゴリズムとして知られて幅優先探索アルゴリズムは、検索アルゴリズムの一つは、最も単純なグラフであり、連結グラフのトラバーサルポリシーです。Dijksta単一ソース最短パスアルゴリズムと最小スパニングツリーアルゴリズムプリムはBFS同様のアイデアを使用しています。

基本的な考え方
ここに画像を挿入説明
擬似コード説明
(1)は頂点vをキューに入れます。
(2)キューが継続空されていない、そうでなければ、アルゴリズムは終了します。
(3)キューヘッドチームポイントを得るためにV、V訪問頂点と頂点vマークがアクセスされました。
(4)は、頂点v wの最初の隣接頂点を見つけます。
(5)隣接する頂点は、次にキューwは、アクセスされていないwはV場合。
(6)は、ステップ(5)に行くwは別の新しい頂点vの隣接頂点を探し続けています。
すべてのネイバーが訪問されていないまで、頂点vが処理します。ステップ(2)に移動します。
説明擬似コードの洗練

訪問アクセスフラグ配列[N]、初期値が0であるの確立、頂点Aがアクセスされ、対応する要素は、インデックスに設定されています。
(1)は、キューQを初期化し、訪問[N] = 0;
(2)訪問頂点V、訪問[V] = 1 ; キューQに頂点v;
(3)一方、(キューQ非空)
V =キューQチーム、ヘッド素子デキュー
最初の隣接頂点v W =;
一方(本w)の
WをW、アクセス頂点にアクセスしていない場合、
訪問[W] = 1;
;キューQ W頂点
、頂点vでW =隣人。

(BFS隣接行列を得ます)

#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define N 9 //顶点数
int Visited[N];
int AdjMatrix[N][N]=//邻接矩阵
	{{0,1,0,0,0,0,0,0,0},
	{1,0,0,0,1,1,0,1,1}, 
	{0,0,0,0,0,1,1,0,0}, 
	{0,0,0,0,1,0,0,0,1}, 
	{0,1,0,1,0,1,1,0,1}, 
	{0,1,1,0,1,0,1,0,0}, 
	{0,0,1,0,1,1,0,0,0}, 
	{0,1,0,0,0,0,0,0,0}, 
	{0,1,0,1,1,0,0,0,0}};
/*==========================================
函数功能:找顶点v相邻点i的后一个相邻点
函数输入:顶点v,v的相邻点i
函数输出:i的后一个相邻点下标,无相邻点时返回-1
=============================================*/
int FindVex(int v,int i)
{
	while (AdjMatrix[v][i]==0) i++;     
	if (i<N) return i;
	else return -1; 
}

/*==========================================
函数功能:基于邻接矩阵的BFS遍历
函数输入:图的遍历起始顶点v
函数输出:无
屏幕输出:图的BFS序列
=============================================*/
void GraphBFS(int v)
{
	int flag;
	SeqQueue struc;
	SeqQueue *sq;
	sq=&struc;
	int w,k;
	int count=0;

	initialize_SqQueue(sq);
	printf("BFS序列:");
	printf("%d ",v);
	Visited[v]=1;
	count++;
	flag=Insert_SqQueue(sq,v);			//首结点入队
	while (!Empty_SqQueue(sq))			//队列Q非空
	{
		if (count==N) break;
		k=Delete_SqQueue(sq);			//队列Q的队头元素出队,返回元素下标位
		v=sq->data[k];
		w=FindVex(v,0); 				//w=顶点v的第一个邻接点;
		while(w!=-1)
		{
            if( Visited[w]!=1)				//如果w未访问过
		   {
			   Visited[w]=1;			//置w访问标记
			   printf("%d ",w);
			   count++;
		   }
		       flag=Insert_SqQueue(sq,w);	//顶点w入队列Q
                 w=FindVex(v,w+1);		//w=顶点v的下一个邻接点
		}
	}
	printf("\n");
}

int main()
{
	GraphBFS(0);//从顶点1开始遍历,对应下标为0
	return 0;
}

削除するインデックスノード- int型のkを取ります。
キューは常に0または1のノードです。

BFSアルゴリズムが議論します

問題解決のためのアルゴリズムは、幅優先探索ステップ:

1)状態ノードを定義します

幅優先探索アルゴリズムは、問題を解決するためには、状態、指示異なる状態の特性とデータ構造との関係を構築する必要がある場合。

2)拡張ルールノードを決定します

問題与えられた条件が、ノードから、このプロセスは、多くの場合、拡張と呼ばれる、1つ以上の新しいノードを生成することができます。検索結果内のノード間の関係は、一般的にツリーを答えと呼ばれ、ツリーとして表すことができます。検索アルゴリズム検索処理が実際に初期条件と拡張ルールソリューションツリーを構築するに基づいています。検索プロセスは、実際に初期条件と回答ツリー構造に基づいた検索アルゴリズムで、目標状態のプロセスに沿ってノードを検索するためのルールを展開します。

幅優先探索アルゴリズムは、応答ツリーノード拡張を順次実行開始ノードへの近接の程度に基づいています。、一つ一つの第一層、第二層を得ノード内のすべてのノードに拡張されていない場合、ノードの宛先ノードが、生成されたか否かを確認しながら最初に、生成された第1のグランド層、及び第2のチェック成層点は、宛先ノードが、含まれている...、N + 1層は、拡張接合する前に、それぞれの可能な状態のためにn層のノードを考慮しなければなりません。問題を解決するための値が同じであるため、同じ層のノードのために、私たちはどのような順序でそれらを拡張することができます。ここで氏原理は、最初のノードを拡大することです。

3)検索戦略

検索を容易にするために、テーブルは、ノードのすべてを格納するために設けられています。幅優先探索アルゴリズムので、テーブルのストレージノードは、通常、キューデータ構造に設計されたので、展開するノードに社長の原則を満足します。
検索ステップは、一般的に:
(1)新しいノードが生成される場合、それは、拡張することができるかどうかを拡張ルールチェックに応じてキューヘッダから削除ノード。
新しいノードが戻って最初の(1)のステップへ、その後、このノードをあきらめ、キューに登場している場合(2)は、それがすでにキューに存在しているかどうかを確認するために、新たに生成されたノードを確認してください。新しいノードがキューに現れていない場合はそれ以外の場合は、その後、キューの最後に追加します。
(3)宛先ノードであれば、新しいノードを確認してください。新しいノードが宛先ノードでない場合、最初のステップ(1)に戻り、その後、キューの拡大ヘッドからノードを削除し、新しいノードが宛先ノードである場合、検索は、プログラムを終了成功です。
検索は、最終的に2つのノードが生成されることがあります。ターゲット・ノードを見つけることなく、すべてのノードを展開または完了、ターゲット・ノードを見つけます。
ターゲットノードは、制限されたレベルのソリューションツリー上に存在する場合、幅優先探索アルゴリズムが最適経路を確保する方法を見つけることができるようになり、幅優先探索アルゴリズムは、最適解を得るために特に適用可能です。パスに解決する問題が与えられたときにそれが拡張された各ノード、すなわちノードAのソースを保存する必要があります。

幅優先アルゴリズムは、最初のノードからの逸脱を必要とし、徐々に問題の解決策を見つけるために拡張しました。問題が解けるであれば、それは答えツリー上の層に常にあります。
ここに画像を挿入説明

図深度優先走査DFS

ツリーの先行順走査に似た深さ優先探索マップ、検索戦略は、「深い」マップを検索し、可能な限り続いています。
それは開始点としてありますが、エッジを検出していない場合は、それを探求し続けるために、このエッジに沿っています。それは、これまでソースノードから到達可能なすべてのノードに行われて発見されました。
ここに画像を挿入説明
ここに画像を挿入説明
DFSアルゴリズム分析
ここに画像を挿入説明
所定の順序には、隣接するアクセスポイントが存在しないためには、深さ優先順序は一意ではありません。

DFS算法描述:
ここに画像を挿入説明
注:以上为连通图的 DFS 算法。非连通图的 DFS算法在上述连通图的算法基础上再检查是否有剩余顶点,如果仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复 DFS 过程,直至图中所有顶点均已被访问为止。

基于邻接矩阵的 DFS 递归方法程序实现

/*==========================================
函数功能:基于邻接矩阵的图DFS遍历递归算法
函数输入:图的遍历起始顶点v
函数输出:无
屏幕输出:图的DFS序列
=============================================*/
void GraphDFS(int i) 
{  int j;
   printf("%d ",i+1); //i+1是因为图中顶点编号从1开始,存储从0开始
   Visited[i]=1;
   for (j=0; j<N; j++)
         if ((AdjMatrix[i][j]==1) && (!Visited[j]) )
             GraphDFS(j);  		//被调用n次
}

基于邻接表的DFS递归方法程序实现
ここに画像を挿入説明

/*==========================================
函数功能:基于邻接表的DFS遍历递归算法
函数输入:图的遍历起始顶点v
函数输出:无
屏幕输出:图的DFS序列
=============================================*/
void GraphDFS_L(int vi)	
//从vi出发深度优先搜索遍历图,图用邻接表表示
{	AL_AdjNode *p;
	printf("%d ",VexList[vi].vertex+1);	//访问顶点vi  
	Visited[vi]=1;            	//标记vi已被访问 
	p=VexList[vi].link;       	//取vi的边表头指针 
	while( p!=NULL )          	//依次搜索vi的邻接点 
	{
	  if (Visited[p->adjvex]==0)
	  //从vi的未曾访问过的邻接点出发进行深度优先搜索遍历
        GraphDFS_L(p->adjvex);  
	    p=p->next;
	}
} 

过程:访问(打印)->在邻接点递归
找邻接点(全部都在边表)并打印它,while循环条件内可增设一计数变量作为结束标志。

基于邻接表的非递归方法程序实现

/*==========================================
函数功能:图的DFS遍历非递归算法
函数输入:图的遍历起始顶点vi
函数输出:无
屏幕输出:图的DFS序列
=============================================*/
void DFS(int vi)
{
	SeqStack struc;
	SeqStack *s;
	int vj; 
	int flag;
	
	s=&struc;	
	initialize_SqStack( s );				//栈初始化
	Visited[vi]=1;						//访问顶点vi
	 printf("%d ",vi+1);
	flag=Push_SqStack(s,vi);				//顶点vi入栈
	while(!StackEmpty_SqStack(s))			//栈非空
	{
		vj=0;
     	flag=Get_SqStack(s, &vi);			//vi=栈顶元素(不出栈)
		//vi有邻接点且未被访问,跳出
        	while(!(AdjMatrix[vi][vj]==1 && Visited[vj]==0)) vj++;
         	if (vj<N) //访问vj
		{
			printf("%d ",vj+1);
			Visited[vj]=1;
             	flag=Push_SqStack(s,vj);		//vj进栈;
		 }
         else
		{
             flag=Pop_SqStack(s, &vi);		//vi出栈;
		}
	}
}

测试用图

需先把邻接矩阵转换成邻接表或手动输入邻接表

AdjMatrix[N][N]=
{{0,1,1,0,0,0,0,0},
{1,0,0,1,1,0,0,0},
{1,0,0,0,0,1,1,0},
{0,1,0,0,0,0,0,1},
{0,1,0,0,0,0,0,1},
{0,0,1,0,0,0,1,0},
{0,0,1,0,0,1,0,0},
{0,0,0,1,1,0,0,0}};
ここに画像を挿入説明

图的遍历问题分类

遍历完所有的边而不能有重复,即所谓“一笔画问题”或“欧拉路径”;
遍历完所有的顶点而没有重复,即所谓“哈密尔顿问题”;

遍历完所有的边可以有重复,即所谓“中国邮递员问题”;
遍历完所有的顶点而可以重复,即所谓“旅行推销员问题”。

图的遍历小结
ここに画像を挿入説明

发布了23 篇原创文章 · 获赞 3 · 访问量 1364

おすすめ

転載: blog.csdn.net/herui7322/article/details/104376424