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
-
C言語のポインターを使用した算術演算について説明しますか?
ポインタは、他の変数のアドレスを格納する変数です。 ポインタの宣言、初期化、アクセス 次のステートメントを検討してください- int qty = 179; ポインタの宣言 int *p; 「p」は、別の整数変数のアドレスを保持するポインタ変数です。 ポインタの初期化 アドレス演算子(&)は、ポインタ変数を初期化するために使用されます。 int qty = 175; int *p; p= &qty; ポインタを使用した算術演算 ポインタ変数は式で使用できます。たとえば、ポインタ変数が適切に宣言および初期化されている場合、次のステートメントが有効です。 a) *p1 +
-
構造概念を使用してC言語でビットフィールドを説明する
ビットフィールドは、変数のサイズをビット単位で指定するために使用されます。通常、構造内で定義されます。 ビットフィールド:1バイト=8ビット たとえば、 例を以下に説明します- Struct info{ int x:2; }; ここで、xは2ビットを占めています。 範囲外のビットフィールドに値を割り当てることは無効です。 サイズとアドレス演算子はビットフィールドに適用できないため、scanfステートメントを使用してビットフィールドの値を入力することはできません。 ビットフィールドに割り当てることができるデータ型は、int、signed int、uns