前言
爲什麼要使用C語言
因爲c語言中基本沒有數據結構, 所有的數據結構都需要自己來定義, 看一個人有沒有真正的理解這個算法, 那麼用C語言能寫出來就算是真正的明白了這個算法的過程, 所以c語言是檢驗技術的一個有力的方法
爲什麼要弄明白這些算法
我的老師王老師說過, 會底層的纔是人才, 應用都是最基礎的, 都是小兒科 核心思想在別人那裏想給你用就給你用, 不給你用你也沒有辦法.
簡要說明
BFS和DFS是數據結構中圖的遍歷中使用的算法, 跟二叉樹的遍歷有着異曲同工之妙.
BFS
BFS, Breadth First Search, 廣度優先遍歷, 遍歷思路爲: 從最開始遍歷的結點開始, 按順序一次找到所有的距離當前結點最近的結點, 知道所有的結點都被遍歷完成.
這樣的話我們可以用一個隊列的數據結構來實現這個BFS遍歷方法
隊列 -> BFS
- 將開始訪問的結點放入隊頭中
- 將隊頭的臨接結點放入隊列中
- 開始的結點pop彈出
- 重複2, 3直到隊列爲空
- 注意: 每次只pop彈出一個元素, 放入所有的鄰接結點, 隊列中的元素不重複(邏輯)
DFS
DFS, Deepth First Search, 深度優先遍歷, 遍歷思路爲: 從最開始遍歷的結點, 一條路走到黑, 知道五路可走, 再返回一個有路的結點, 最新的路(也就是訪問未訪問的結點), 直到所有的結點都被訪問/(遍歷)過
與BFS相似, 我們可以用一個棧的數據結構來實現這個DFS算法
棧 -> DFS
- 將開始訪問的結點的放入棧中
- 將棧中的一個元素pop彈出,
- 當前彈出的元素的鄰接結點全部放入棧中
- 重複2, 3, 直到棧爲空
- 注意: 每次在棧中只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;
}