搜索算法
搜索算法有很多种类型,一般来说就是深度优先搜索,广度优先搜索,A*搜索,IDA*搜索这四种类型的搜索,而本篇讲述的就是其中最核心,最简单的搜索深度优先搜索和广度优先搜索。
DFS算法简述
深度优先搜索是一种适用于树形结构的搜索,它和数据结构栈紧密相连。对于这种算法而言,它的主要步骤大致如下:
- 找到当前可以拓展的点,那么立即走入这个分支点。
- 如果当前搜索分支,无效或者已经找到目标,那么退回到上一步,即回溯。
- 每一个点最多会被访问两次。访问含义是入栈一次,出栈一次。
DFS性质
DFS序列就是深度优先搜索最为重要的性质,它可以将一个子树变成一个区间。
代码实现(递归)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_N 10000 typedef struct Node { int vertex; struct Node *next; } Node, *LinkedList; LinkedList insert_node(LinkedList head, int index) { Node *node = (Node *)malloc(sizeof(Node)); node->vertex = index; node->next = head; head = node; return head; } typedef struct Graph { LinkedList edges[MAX_N]; int n; int visited[MAX_N]; } Graph; void init(Graph * g, int n) { g->n = n; for (int i = 0; i < g->n; ++i) { g->edges[i] = NULL; } } void insert(Graph *g, int x, int y) { if (x < 0 || x >= g->n || y < 0 || y >= g->n) { return ; } g->edges[x] = insert_node(g->edges[x], y); g->edges[y] = insert_node(g->edges[y], x); } void clear(Graph *g) { for (int i = 0; i < g->n; ++i) { Node *head = g->edges[i]; while (head != NULL) { Node *delete_node = head; head = head->next; free(delete_node); } } free(g); } void dfs(Graph *g, int index) { printf("%d ", index); g->visited[index] = 1; for (Node *tmp = g->edges[index]; tmp != NULL; tmp = tmp->next) { if (!g->visited[tmp->vertex]) { dfs(g, tmp->vertex); } } return; } int main() { int n, m, k; scanf("%d %d", &n, &m); Graph *graph = (Graph *)malloc(sizeof(Graph)); init(graph, n); for (int i = 0; i < m; ++i) { int x, y; scanf("%d %d", &x, &y); insert(graph, x, y); } scanf("%d", &k); dfs(graph, k); clear(graph); return 0; }
算法例题
BFS算法简述
广度优先搜索和深度优先搜索恰恰相反,它是一种适用于图型结构的搜索,它和数据结构队列紧密向量。对于这种算法而言,它主要的步骤大致如下所示:
- 找到当前可以拓展的点,将它放入候选队列之中。
- 每次选取候选队列的队头,作为当前状态。
BFS性质
对于广度优先搜索而言,它是一种逐层遍历的算法,所有状态按照入队的先后顺序具有层次单调性,也就是所谓的步数单调性质,如果每一次拓展恰好对应一部,那么当第一个状态第一次被访问(入队),就会得到从起始状态到达该状态的最少步数。
代码实现(队列)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_N 10000 typedef struct Queue { int *data; int head, tail, length; } Queue; void init_queue(Queue *q, int length_input) { q->data = (int *)malloc(sizeof(int) * length_input); q->length = length_input; q->head = 0; q->tail = -1; } void push(Queue *q, int element) { if (q->tail + 1 < q->length) { q->tail++; q->data[q->tail] = element; } } int front(Queue *q) { return q->data[q->head]; } void pop(Queue *q) { q->head++; } int empty(Queue *q) { if (q->head > q->tail) { return 1; } else { return 0; } } void clear_queue(Queue *q) { free(q->data); free(q); } typedef struct Node { int vertex; struct Node *next; }Node, *LinkedList; LinkedList insert_node(LinkedList head, int index) { Node *node = (Node *)malloc(sizeof(Node)); node->vertex = index; node->next = head; head = node; return head; } typedef struct Graph { LinkedList edges[MAX_N]; int visited[MAX_N]; int n; }Graph; void init_graph(Graph *g, int n) { g->n = n; memset(g->visited, 0, sizeof(g->visited)); for (int i = 0; i < g->n; ++i) { g->edges[i] = NULL; } } void insert(Graph *g, int x, int y) { if (x < 0 || x >= g->n || y < 0 || y >= g->n) { return ; } g->edges[x] = insert_node(g->edges[x], y); g->edges[y] = insert_node(g->edges[y], x); } void clear_graph(Graph *g) { for (int i = 0; i < g->n; ++i) { Node *head = g->edges[i]; while (head != NULL) { Node *delete_node = head; head = head->next; free(delete_node); } } free(g); } void bfs(Graph *g, int id) { Queue *queue = (Queue *)malloc(sizeof(Queue)); init_queue(queue, g->n); printf("%d ", id); g->visited[id] = 1; push(queue, id); while (!empty(queue)) { int tmp = front(queue); pop(queue); for (Node *adj = g->edges[tmp]; adj != NULL; adj = adj->next) { if (!g->visited[adj->vertex]) { printf("%d ", adj->vertex); push(queue, adj->vertex); g->visited[adj->vertex] = 1; } } } clear_queue(queue); } int main() { int n, m, k; scanf("%d %d", &n, &m); Graph *graph = (Graph *)malloc(sizeof(Graph)); init_graph(graph, n); for (int i = 0; i < m; ++i) { int x, y; scanf("%d %d", &x, &y); insert(graph, x, y); } scanf("%d", &k); bfs(graph, k); clear_graph(graph); return 0; }
算法例题
参考资料:
https://www.acwing.com/blog/content/173/
https://www.acwing.com/blog/content/173/