Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語を使用したDFSの実装


深さ優先探索(DFS)は、グラフをトラバースし、戻ってくる前にすべてのノードにアクセスして判断できるアルゴリズムです。また、2つのノード間にパスが存在するかどうかを判別します。

グラフまたはツリーを詳細に検索します。

アルゴリズム

以下に示すのは、深さ優先探索(DFS)を実装するためのアルゴリズムです-

ステップ1 −最初はスタックが空です。

ステップ2 −訪問するノードがスタックに存在しない場合は、そのノードをスタックにプッシュして、訪問済みとしてマークします。

ステップ3 −次に、現在のノードが検索条件に一致するかどうかを確認します。

ステップ3.1 −そこにあれば、完了です。

ステップ4 −それ以外の場合は、現在のノードから隣接するすべてのノードに移動する必要があります。

ステップ4.1 −次に、そのすべてのタイプのノードにランダムな順序でアクセスし、検索を続けます。

ステップ5 −隣接するすべてのノードがすでにアクセスされている場合は、行き止まりになります。

ステップ6 −以前にアクセスしたノードに移動し、スタックから最近のノードをポップします。

ステップ7 −すべてのノードが検索された場合、または回答が得られた場合、アルゴリズムは終了します。

プログラム

以下は、深さ優先探索(DFS)の実装のためのCプログラムです。 −

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX 5
void addVertex(char);
void addEdge(int,int );
void displayVertex(int);
void depthFirstSearch();
int getAdjUnvisitedVertex(int);
struct Vertex {
   char label;
   bool visited;
};
//stack variables
int stack[MAX];
int top = -1;
//graph variables
//array of vertices
struct Vertex* lstVertices[MAX];
//adjacency matrix
int adjMatrix[MAX][MAX];
//vertex count
int vertexCount = 0;
//stack functions
void push(int item) {
   stack[++top] = item;
}
int pop() {
   return stack[top--];
}
int peek() {
   return stack[top];
}
bool isStackEmpty() {
   return top == -1;
}
//graph functions
//add vertex to the vertex list
void addVertex(char label) {
   struct Vertex* vertex = (struct Vertex*) malloc(sizeof(struct Vertex));
   vertex->label = label;
   vertex->visited = false;
   lstVertices[vertexCount++] = vertex;
}
//add edge to edge array
void addEdge(int start,int end) {
   adjMatrix[start][end] = 1;
   adjMatrix[end][start] = 1;
}
//display the vertex
void displayVertex(int vertexIndex) {
   printf("%c ",lstVertices[vertexIndex]->label);
}
//get the adjacent unvisited vertex
int getAdjUnvisitedVertex(int vertexIndex) {
   int i;
   for(i = 0; i < vertexCount; i++) {
      if(adjMatrix[vertexIndex][i] == 1 && lstVertices[i]->visited == false) {
         return i;
      }
   }
   return -1;
}
void depthFirstSearch() {
   int i;
   //mark first node as visited
   lstVertices[0]->visited = true;
   //display the vertex
   displayVertex(0);
   //push vertex index in stack
   push(0);
   while(!isStackEmpty()) {
      //get the unvisited vertex of vertex which is at top of the stack
      int unvisitedVertex = getAdjUnvisitedVertex(peek());
      //no adjacent vertex found
      if(unvisitedVertex == -1) {
         pop();
      } else {
         lstVertices[unvisitedVertex]->visited = true;
         displayVertex(unvisitedVertex);
         push(unvisitedVertex);
      }
   }
   //stack is empty, search is complete, reset the visited flag
   for(i = 0;i < vertexCount;i++) {
      lstVertices[i]->visited = false;
   }
}
int main() {
   int i, j;
   for(i = 0; i < MAX; i++) // set adjacency {
      for(j = 0; j < MAX; j++) // matrix to 0
         adjMatrix[i][j] = 0;
      addVertex('S'); // 0
      addVertex('A'); // 1
      addVertex('B'); // 2
      addVertex('C'); // 3
      addVertex('D'); // 4
      addEdge(0, 1); // S - A
      addEdge(0, 2); // S - B
      addEdge(0, 3); // S - C
      addEdge(1, 4); // A - D
      addEdge(2, 4); // B - D
      addEdge(3, 4); // C - D
      printf("Depth First Search: ");
      depthFirstSearch();
return 0;
}

出力

上記のプログラムを実行すると、次の結果が得られます-

Depth First Search: S A D B C

  1. C言語のポインターを使用した算術演算について説明しますか?

    ポインタは、他の変数のアドレスを格納する変数です。 ポインタの宣言、初期化、アクセス 次のステートメントを検討してください- int qty = 179; ポインタの宣言 int *p; 「p」は、別の整数変数のアドレスを保持するポインタ変数です。 ポインタの初期化 アドレス演算子(&)は、ポインタ変数を初期化するために使用されます。 int qty = 175; int *p; p= &qty; ポインタを使用した算術演算 ポインタ変数は式で使用できます。たとえば、ポインタ変数が適切に宣言および初期化されている場合、次のステートメントが有効です。 a) *p1 +

  2. 構造概念を使用してC言語でビットフィールドを説明する

    ビットフィールドは、変数のサイズをビット単位で指定するために使用されます。通常、構造内で定義されます。 ビットフィールド:1バイト=8ビット たとえば、 例を以下に説明します- Struct info{    int x:2; }; ここで、xは2ビットを占めています。 範囲外のビットフィールドに値を割り当てることは無効です。 サイズとアドレス演算子はビットフィールドに適用できないため、scanfステートメントを使用してビットフィールドの値を入力することはできません。 ビットフィールドに割り当てることができるデータ型は、int、signed int、uns