问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

算法基础:递归、搜索与回溯详解

创作时间:
作者:
@小白创作中心

算法基础:递归、搜索与回溯详解

引用
1
来源
1.
https://cloud.tencent.com/developer/article/2499039

递归、搜索和回溯是计算机科学中重要的算法概念,广泛应用于数据结构和算法设计中。本文将通过具体的例子和代码,帮助读者深入理解这些算法的核心思想和应用场景。

1. 什么是递归

递归是一种在函数定义中调用函数自身的方法。下面通过二叉树遍历和排序算法来说明递归的应用。

1.1 二叉树的遍历

以后序遍历为例,遍历过程如下:

  1. 遍历根节点的左子树
  2. 遍历根节点的右子树
  3. 最后遍历根节点

对于任意子树,都遵循相同的遍历顺序。

1.2 快速排序

快速排序的基本步骤:

  1. 选择一个基准元素
  2. 将小于基准的元素放到左边,大于基准的放到右边
  3. 对左右两部分递归排序

1.3 归并排序

归并排序的过程:

  1. 从中间将数组分为两部分
  2. 递归地对左右两部分进行排序
  3. 合并两个有序数组

2. 为什么使用递归

递归适用于将问题分解为相似的子问题,并使用相同的方法解决这些子问题。

3. 如何理解递归

3.1 递归展开细节图

初学者常通过递归展开图来理解递归,但这种方法并不总能简化理解。

3.2 二叉树遍历中的递归

二叉树遍历是递归的经典应用,每个子树的遍历方法相同。

3.3 宏观看待递归

跳出细节,关注问题本质,使用递归解决子问题。

下面是DFS和归并排序的伪代码示例:

void dfs(treenode* root)
{
    // 结束条件:遇到叶子结点
    if (root == NULL)
    {
        return;
    }
    dfs(root->left);
    dfs(root->right);
    printf("%d", root->val);
}
void merge(int* nums, int left, int right)
{
    // 递归结束的出口
    if (left >= right)
    {
        return;
    }
    int mid = (left + right) / 2;
    merge(nums, left, mid);
    merge(nums, mid + 1,right);
    // 合并两个有序数组
}

4. 如何写好递归

  1. 函数头的书写:识别主问题中的子问题,判断是否可以用相同方法解决。
  2. 函数体的书写:专注于一个子问题的实现。
  3. 结束条件:确定递归终止的条件。

5. 搜索算法

5.1 深度优先搜索(DFS)

DFS的特点是一条路走到黑,直到无法继续再回溯。

5.2 宽度优先搜索(BFS)

BFS按层遍历,一层一层地进行搜索。

6. 回溯

回溯是深度优先搜索的一种特例,常用于解决组合、排列等问题。例如,在迷宫问题中,当遇到死胡同时需要回退到上一个决策点重新选择路径。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号