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