首页 » 软件开发 » 算法|在了解诸多细节之前先要整体上了解算法的分类(算法递归回溯排序函数)

算法|在了解诸多细节之前先要整体上了解算法的分类(算法递归回溯排序函数)

南宫静远 2024-07-24 00:23:32 0

扫一扫用手机浏览

文章目录 [+]

在任何一个程序中,算法无处不在(表现为函数或类方法)。
或经典,复用率高,或普通,利用率低。

在程序内,算法无处不在(用某种编程语言的函数来描述),或大或小,或复杂或简单,或复用性高或复用性低。
与数据结构也有千丝万缕的关系。
如何理解算法呢?可以从算法分类入手,在整体上把握其全貌,再去了解其细节。
因为从方法论来说,理解一复杂事物,需要从整体与细节两个方面的视点,交叉去深入了解,避免盲人摸象,避免只见树木不见森林

1 与数据结构相关的算法和独立于数据结构的算法

我们知道,计算机的计算不单纯只是数值的计算,很大一部分是非数值的数据处理(称为非数值算法),这一部分的数据就涉及到数据结构的概念。

算法|在了解诸多细节之前先要整体上了解算法的分类(算法递归回溯排序函数) 软件开发
(图片来自网络侵删)

算法与数据结构相互影响。
选择合适的数据结构,直接关乎的算法的选择,同时,选择的算法又会反过来影响数据结构的选择,有时,就是这样反复影响,来找到最佳的数据结构与算法的匹配。

2 经典算法思想

经典的算法总是以经典的算法思想为指导:

2.1 大事化小的算法思想

2.1.1 分治法

分治法解为独立的子问题(Divide),解决(solve),合并(combine)(如果需要),如快速排序、折半查找(可以循环迭代实现,也可以递归实现)。

在分治算法中,各个子问题形式相同,解决的方法也一样,因此我们可以使用递归算法快速解决,递归是彰显分治法优势的利器。

除了分治法,还有减治法、变治法的说法。

减治法是利用一个问题给定实例的解和同样问题较小实例的解之间的关系。
一旦建立了这样一种关系,我们既可以自顶至下(递 归)也可以自底至上地运用它(非递归)。
典型实例如阶乘。

变治法是一组基于变换思想 的技术,用来把问题变换成一种更容易解决的类型。
如有最简单的实例如最大公约数的辗转求法。

变治技术有三种主要的类型:实例化简、改变表现和问题化简。

实例化简是一种把问题的实例变换成相同问题的另一个实例的技术,这个新的实例有一些特殊的属性,使得它更容易被解决。
列表预排序、高斯消去法和AVL 树都是这种技术的好例子。

改变表现指的是将一个问题实例的表现改变为同样实例的另一种表现。
如用2-3树表示集合、堆和堆排序、求多项式的霍纳法则以及两种二进制幂算法。

问题化简提倡把一个给定的问题变换为另一个可以用已知算法求解的问题。
如那些化简为线性规划问题和化简为图问题是尤其重要的。

2.1.2 动态规划法

动态规划法问题重叠或不独立,无后效性,分阶段递推,如利用额外数组求解斐波那契问题。

动态规划是1957年理查德·贝尔曼在Dynamic Programming一书中提出来的。
“Programming”不是编程的意思,而是指一种表格处理法。
我们把每一步得到的子问题结果存储在表格里,每次遇到该子问题时不需要再求解一遍,只需要查询表格即可。

求解动态规划问题,如何确定状态和转移方程是关键,也是难点。
不同的状态和转移方程可能导致不同的算法复杂度。

2.1.3 贪婪法

贪婪法具有最优子结构,不回溯(一旦选择,不再反悔),堆叠;如背包问题,最优装载问题,最短路径问题、哈夫曼编码最小生成树。

贪心选择性质是指原问题的整体最优解可以通过一系列局部最优的选择得到。
将原问题变为一个相似的但规模更小的子问题,而后的每一步都是当前最佳的选择。
这种选择依赖于已做出的选择,但不依赖于未做出的选择。

2.1.4 三类大事化小的算法思想的比较

动态规划也是一种分治思想,但与分治算法不同的是,分治算法是把原问题分解为若干子问题,自顶向下求解各子问题,合并子问题的解,从而得到原问题的解。
动态规划也是把原问题分解为若干子问题,然后自底向上,先求解最小的子问题,把结果存储在表格中,再求解大的子问题时,直接从表格中查询小的子问题的解,避免重复计算,从而提高算法效率。
贪心法与动态规划法一样,都具有最优子结构。

2.2 解空间枚举的算法思想

2.2.1 回溯法

回溯法是以深度优先(DFS,以栈辅助实现)(或递归)的方式搜索问题的解空间来求最优解,如分书问题、n皇后问题。

回溯法是按照深度优先搜索策略,根据隐约束(约束函数和限界函数),在解空间中搜索问题的可行解或最优解,当发现当前结点不满足求解条件时,就回溯尝试其他的路径。

回溯法是一种“能进则进,进不了则换,换不了则退”的搜索方法。

隐约束(剪枝函数)包括约束函数和限界函数。

对能否得到问题的可行解的约束称为约束函数,对能否得到最优解的约束称为限界函数。
剪枝函数可以剪掉得不到可行解或最优解的分支,避免无效搜索,提高搜索的效率。
剪枝函数设计得好,搜索效率就高。

如果问题只是要求可行解,则只需要设定约束函数即可,如果要求最优解,则需要设定约束函数和限界函数。

2.2.1 分支限界法

分支限界法是以广度优先(BFS,以队列辅助实现)的方式搜索问题的解空间来求最优解,如电路板布线问题。

搜索前要定义判断标准(约束函数或限界函数)。

解空间的大小和剪枝函数的好坏都直接影响搜索效率,因此这两项是搜索算法的关键。

2.3 递归与上述算法思想的结合

2.3.1 递归与迭代

迭代:反复利用变量旧值推出新值

折半查找(迭代)

归并查找(迭代)

2.3.2 递归与分治

分治法:问题的分解,问题规模的分解。

折半查找(递归)

归并查找(递归)

快速排序(递归)

2.3.3 递归与回溯法

直接枚举法的优点是思路和程序都很简单,缺点在于无法简便地减小枚举量——必须生成(generate)所有可能的解,然后一一检查(test)。

当把问题分成若干步骤并递归求解时,如果当前步骤没有合法选择,则函数将返回上一级递归调用,这种现象称为回溯。
正是因为这个原因,递归枚举算法常被称为回溯法,应用十分普遍。

回溯法(backtracking)中,生成和检查过程可以有机结合起来,从而减少不必要的枚举。
在某种情况下,递归函数将不再递归调用它自身,而是返回上一层调用,这种现象称为回溯(backtracking)。

递归与回溯的共通点是两者都要考虑回归,所以一些回溯法可以很方便地很递归法去实现。

不考虑回归

考虑回归(隐式或显式栈)

递推

递归

贪心算法

回溯法

递归与回溯:

void recursion(){ if( test for simple case) Compute a simple solution without using recursion. else { 1 Break the problem down into subproblems of the same form. 2 Solve each of the subproblems by calling this function recursively. 3 Reassemble the subproblem solutions into a solution for the whole. }}void Backtracking(){ If you are already at a solution, report success. for ( every possible choice in the current position ) { 1 Make that choice and take one step along the path. 2 Use recursion to solve the problem from the new position. 3 If the recursive call succeeds, report the success to the next higher level. 4 If not, back out of the current choice to restore the previous state. } Report failure.}

2.4 经典问题与经典算法思想的结合

如背包问题就是一个经典的问题,可以使用多种算法思想来考虑这一问题的解法。

3 其它的一些经典算法类别

如遗传算法、模拟算法。

数值算法:概率算法、高精度算法、排列组合问题相关的算法等。

4 经典领域的经典算法

数据处理有两个经典领域:排序、查找,涉及到大量算法算法的运用。

冒泡排序

顺序查找

选择排序

二分查找

插入排序

三分查找

希尔排序

分块查找

归并排序

B树查找

快速排序

哈希查找

计数排序

插值查找

基数排序

树表查找

拓扑排序

z字符串查找

桶排序

斐波那契查找

堆排序

KMP字符串查找

圈排序

Rabin-Karp字符串查找

梳排序

A搜索

基数排序

深度优先搜索

鸽巢排序

广度优先搜索

煎饼排序

二叉树排序

鸡尾酒排序

5 如何设计一个算法?

5.1 定义动作

确定一系列的步骤,每一步都只完成一个动作。

5.2 精化

剔除重复的步骤;

不同的步骤完成的动作可能相同,但它 们产生的结果不能相同。

5.3 泛化

使算法对尽可能多的具体问题具有适应性。

ref

https://gitmind.cn/app/doc/5b9ac801b4612d92737aa71fad6e3caf

https://gitmind.cn/app/doc/cc2af81a87818bff55364d1d4abbe9ac

-End-

标签:

相关文章

语言中的借用,文化交融的桥梁

自古以来,人类社会的交流与发展离不开语言的传播。在漫长的历史长河中,各民族、各地区之间的文化相互碰撞、交融,产生了许多独特的语言现...

软件开发 2025-01-01 阅读1 评论0

机顶盒协议,守护数字生活的新卫士

随着科技的飞速发展,数字家庭逐渐走进千家万户。在这个时代,机顶盒成为了连接我们与丰富多彩的数字世界的重要桥梁。而机顶盒协议,作为保...

软件开发 2025-01-01 阅读1 评论0

语言基础在现代社会的重要性及方法步骤

语言是人类沟通的桥梁,是社会发展的基础。语言基础作为语言学习的基石,对于个人、社会乃至国家的发展具有重要意义。本文将从语言基础在现...

软件开发 2025-01-01 阅读2 评论0

粤语电影,传承文化,点亮时代之光

粤语电影,作为中国电影产业的一朵奇葩,以其独特的地域特色、丰富的文化内涵和鲜明的艺术风格,赢得了广大观众的喜爱。本文将从粤语电影的...

软件开发 2025-01-01 阅读1 评论0

苹果游戏语言,塑造未来娱乐体验的基石

随着科技的飞速发展,游戏产业逐渐成为全球娱乐市场的重要支柱。在我国,游戏产业更是蓬勃发展,吸引了无数玩家和投资者的目光。而在这其中...

软件开发 2025-01-01 阅读1 评论0