• 深度优先搜索与广度优先搜索(含算法例题讲解)


    搜索算法

    搜索算法有很多种类型,一般来说就是深度优先搜索广度优先搜索A*搜索IDA*搜索这四种类型的搜索,而本篇讲述的就是其中最核心,最简单的搜索深度优先搜索和广度优先搜索。

    DFS算法简述

    深度优先搜索是一种适用于树形结构的搜索,它和数据结构栈紧密相连。对于这种算法而言,它的主要步骤大致如下:

    1. 找到当前可以拓展的点,那么立即走入这个分支点。
    2. 如果当前搜索分支,无效或者已经找到目标,那么退回到上一步,即回溯。
    3. 每一个点最多会被访问两次。访问含义是入栈一次,出栈一次。

    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算法简述

    广度优先搜索和深度优先搜索恰恰相反,它是一种适用于图型结构的搜索,它和数据结构队列紧密向量。对于这种算法而言,它主要的步骤大致如下所示:

    1. 找到当前可以拓展的点,将它放入候选队列之中。
    2. 每次选取候选队列的队头,作为当前状态。

    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/

    Min是清明的茗
  • 相关阅读:
    自动驾驶技术其实是一个美丽的谎言
    自动驾驶技术其实是一个美丽的谎言
    Shoutem旨在成为React Native移动应用领域的WordPress
    Mongodb安装
    spring mvc记录各个controller访问开始结束时间,以及耗时时间 线程安全
    python 升级
    SpringMVC的拦截器Interceptor
    使用org.apache.tools.zip实现zip压缩和解压
    使用 ResponseBodyAdvice 拦截Controller方法默认返回参数,统一处理返回值/响应体
    Python爬虫入门教程 4-100 美空网未登录图片爬取
  • 原文地址:https://www.cnblogs.com/MinPage/p/13783477.html
Copyright © 2020-2023  润新知