BFS+DFS非遞歸的實現代碼

前言

爲什麼要使用C語言

因爲c語言中基本沒有數據結構, 所有的數據結構都需要自己來定義, 看一個人有沒有真正的理解這個算法, 那麼用C語言能寫出來就算是真正的明白了這個算法的過程, 所以c語言是檢驗技術的一個有力的方法

爲什麼要弄明白這些算法

我的老師王老師說過, 會底層的纔是人才, 應用都是最基礎的, 都是小兒科 核心思想在別人那裏想給你用就給你用, 不給你用你也沒有辦法.

簡要說明

BFS和DFS是數據結構中圖的遍歷中使用的算法, 跟二叉樹的遍歷有着異曲同工之妙.

BFS

BFS, Breadth First Search, 廣度優先遍歷, 遍歷思路爲: 從最開始遍歷的結點開始, 按順序一次找到所有的距離當前結點最近的結點, 知道所有的結點都被遍歷完成.

這樣的話我們可以用一個隊列的數據結構來實現這個BFS遍歷方法

隊列 -> BFS

  1. 將開始訪問的結點放入隊頭中
  2. 將隊頭的臨接結點放入隊列中
  3. 開始的結點pop彈出
  4. 重複2, 3直到隊列爲空
  5. 注意: 每次只pop彈出一個元素, 放入所有的鄰接結點, 隊列中的元素不重複(邏輯)

DFS

DFS, Deepth First Search, 深度優先遍歷, 遍歷思路爲: 從最開始遍歷的結點, 一條路走到黑, 知道五路可走, 再返回一個有路的結點, 最新的路(也就是訪問未訪問的結點), 直到所有的結點都被訪問/(遍歷)過

與BFS相似, 我們可以用一個棧的數據結構來實現這個DFS算法

棧 -> DFS

  1. 將開始訪問的結點的放入棧中
  2. 將棧中的一個元素pop彈出,
  3. 當前彈出的元素的鄰接結點全部放入棧中
  4. 重複2, 3, 直到棧爲空
  5. 注意: 每次在棧中只pop一個元素, 放入的不一定是一個, 棧中的元素不重複(邏輯).

代碼實現

測試圖

在這裏插入圖片描述

代碼+測試主方法

/*
***********************************************************************
******************** Breadth First Search and *************************
******************** Deepth First Search ******************************
******************** Author : Master_Joe Guangtong*********************
***********************************************************************
*/

#include <stdio.h>
#include <stdlib.h>

// set length of stack or queue
#define MAX_SIZE 32

// Stack data structure
typedef struct stack {
	int length;
	char datas[MAX_SIZE];
} Stack;

// Queue data structure
typedef struct queue {
	int front;
	int rear;
	char datas[MAX_SIZE];
} Queue;

// Graph node data structure
typedef struct node {
	char data;
	struct node* next;
} Node; 

// Graph data structure
typedef struct graph {
	int numNodes;
	// adjacency list
	Node* adjLists[128];
	int visited[128];
} Graph;

/**
 * Create a stack with no element
 */
Stack* create_stack() {
	return malloc(sizeof(Stack));
}

/**
 * Create a queue with no elment
 */
Queue* create_queue() {
	return malloc(sizeof(Queue));
}

/**
 * Create an node with a element
 */
Node* create_node(char value) {
	Node* node = malloc(sizeof(Node));
	node -> data = value;
	node -> next = NULL;
	return node;
}

/**
 * Create Graph with number of vertices
 * @param n number of vertices
 */
Graph* create_graph(int n) {
	Graph* graph = malloc(sizeof(Graph));
	graph -> numNodes = n;
/*
	It is not necessary
	graph -> adjLists = malloc(n * sizeof(Node));
	graph -> visited = malloc(n * sizeof(Node));

	int i;
	for (i = 0; i < n; i++) {
		// No Nodes, no visiting
		graph -> adjLists[i] = NULL;
		graph -> visited[i] = 0;
	}
*/	
	return graph;
}

/**
 * Add edges to a graph
 * @param graph the specified graph to add
 * @param start start node in an edge
 * @param end end node in an edge
 */
void add_edge(Graph* graph, char start, char end) {
	// Add edge from start to end 
	Node* node = create_node(end);
	node -> next = graph -> adjLists[start];
	graph -> adjLists[start] = node;

	// Add edge from end to start
	node = create_node(start);
	node -> next = graph -> adjLists[end];
	graph -> adjLists[end] = node;
}

/**
 * insert a value into a Stack
 * @param stack which stack you will insert into
 * @param value what you want to insert
 */
void push_s(Stack* stack, char value) {
	if (stack -> length != MAX_SIZE) {
		stack -> datas[stack -> length++] = value;
	} else {
		printf("stack overflow!!");
	}
}

/**
 * decide if a queue is full
 * @return {@code 1} is full <br>
 * 		   {@code 0} is not full
 */
int is_full_q(Queue* queue) {
	if (queue -> rear == MAX_SIZE - 1) {
		return 1;
	} 
	else {
		return 0;
	}
}

/**
 * decide if a queue is empty
 * @return {@code 1} is empty
 *         {@code 0} is not empty
 */
int is_empty_q(Queue* queue) {
	if (queue -> front == queue -> rear) {
		return 1;
	}
	else {
		return 0;
	}
}

/**
 * decide if a stack is empty
 * @return {@code 1} is empty
 *         {@code 0} is not empty
 */
int is_empty_s(Stack* stack) {
	if (stack -> length == 0) {
		return 1;
	}
	else {
		return 0;
	}
}

/**
 * insert a value into a Queue
 * @param queue which queue you will insert into
 * @param value what you will insert
 */
void push_q(Queue* queue, char value) {
	if (!is_full_q(queue)) {
		queue -> datas[queue -> rear++] = value;
	} else {
		printf("Queue is full");
	}
}

/**
 * pop element from first
 * @param queue where you will pop
 * @return the first element 
 */
char pop_q(Queue* queue) {
	if (queue -> front != queue -> rear) {
		return queue -> datas[queue -> front++];
	} else {
		return -1;
	}
}

/**
 * pop the end element of a Stack
 * @param stack you will get its last element
 * @return the last element of {@code stakc}
 */
char pop_s(Stack* stack) {
	if (stack -> length != 0) {
		return stack -> datas[--stack -> length];
	} else {
		return -1;
	}
}

/** 
 * Breadth first search
 * @param graph specified graph made bfs
 * @param start start vertex in bfs
 */
void bfs(Graph* graph, char start) {
	Queue* queue = create_queue();
	graph -> visited[start] = 1;
	push_q(queue, start);

	while(!is_empty_q(queue)) {
		char current = pop_q(queue);
		printf("%c\n", current);
		Node* temp = graph -> adjLists[current];

		while (temp != NULL) {
			// Traverse the whole graph
			char adjD = temp -> data;
			if (graph -> visited[adjD] == 0) {
				graph -> visited[adjD] = 1;
				push_q(queue, adjD);
			}
			temp = temp -> next;
		}
	}
}

/** 
 * Deepth first search
 * @param graph specified graph made bfs
 * @param start start vertex in bfs
 */
void dfs(Graph* graph, char start) {
	// Queue* queue = create_queue();
	Stack* stack = create_stack();
	graph -> visited[start] = 1;
	push_s(stack, start);

	while(!is_empty_s(stack)) {
		char current = pop_s(stack);
		printf("%c\n", current);
		Node* temp = graph -> adjLists[current];

		while (temp != NULL) {
			// Traverse the whole graph
			int adjD = temp -> data;
			if (graph -> visited[adjD] == 0) {
				graph -> visited[adjD] = 1;
				push_s(stack, adjD);
			}
			temp = temp -> next;
		}
	}
}

/*
	
*/
int main() {
	Graph* graph = create_graph(5);
	add_edge(graph, 'A', 'B');
	add_edge(graph, 'A', 'C');
	add_edge(graph, 'B', 'C');
	add_edge(graph, 'B', 'D');
	add_edge(graph, 'C', 'D');
	add_edge(graph, 'C', 'E');
	add_edge(graph, 'D', 'E');
	add_edge(graph, 'D', 'F');
	bfs(graph, 'B');
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章