程序的灵魂----算法(一)

来源:互联网 发布:孤独大脑 喻颖正 知乎 编辑:程序博客网 时间:2024/06/10 08:12

一、算法的基本概念

算法是指对解题方案准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。

算法中的指令描述的是一个计算过程,在它的作用下,系统从初始状态和初始输入(也可能没有)开始,经历一系列有限且被明确定义的中间状态,最终产生所要求的输出,并停止于终止状态。

同一个问题,不同的算法,可能会在时间、空间等方面表现出明显的差异,一个算法的优劣可以用时间复杂度和空间复杂度来衡量。

二、算法的基本特征

(1)有穷性

算法必须能在执行有限个步骤后终止

(2)确切性

算法的每一个步骤必须有确切的定义

(3)输入项

算法有规范化的输入,以表示运算对象的初始状态

(4)输出项

算法至少有一个输出,以反映处理的最终结果

(5)可行性

算法中的每个执行步骤都必须能在有限时间内完成

三、算法的基本要素

(1)运算和操作

计算机可以执行的基本操作是以指令的形式描述的,包括如下四类:

算数运算:加、减、乘、除、模等

关系运算:大于、小于、等于、不等于等

逻辑运算:与、或、非等运算

数据传输:输入、输出、赋值等

(2)流程和控制

算法的功能不仅取决于所选用的操作,还与各操作之间的执行顺序有关

四、算法的评定标准

(1)时间复杂度

算法的时间消耗与问题规模之间的函数关系:T(N) = O(F(N))

(2)空间复杂度

算法的空间消耗与问题规模之间的函数关系:S(N) = O(F(N))

(3)正确性

执行算法的结果是否满足要求

(4)可读性

算法本身可供人们阅读的难易程度

(5)健壮性

算法对非正常输入的反应和处理能力,亦称容错性

扩展:常见的时空复杂度有:

(1)常数级复杂度:O(1)

(2)对数级复杂度:O(logN)

(3)线性级复杂度:O(N)

(4)线性对数级复杂度:O(NlogN)

(5)平方级复杂度:O(N^2)

编程灵魂——算法

复杂度曲线越平越好,越陡越差,常数级复杂度最为理想。

扩展:常用数据结构和算法操作效率的对比总结

1. 数据结构部分

编程灵魂——算法

2. 排序算法

编程灵魂——算法

五、算法的思想

(1)递推法

通过计算前面的一些项来得出序列中指定项的值,其思想是把一个复杂而庞大的计算过程转化为简单过程的多次重复,充分发挥计算机速度快且不知疲倦的特点

(2)递归法

把大问题转化为与原问题相似的小问题来求解,递归的神奇之处在于用有限的语句来定义无线的对象集合。递归需要有终止条件,递归前进段和递归返回段,若终止条件不满足则递归前进,否则递归返回。

(3)穷举法

对于要解决的问题,列举出它所有的可能性,逐个判断其中哪些符合问题所要求满足的条件,从而得到问题的解。

(4)贪心算法

自顶向下,以迭代的方式做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到相应子问题的一个最优解,虽然每一步都能保证局部解最优,但最终得到的全局解未必最优。

(5)分治法

把一个复杂问题分成两个或更多仙童或相似的子问题,再把子问题分成更小的子问题。。。直到最后的子问题可以简单地直接求解,原问题的解即子问题解的分并。

(6)动态规划法

将原问题分解为相似的子问题,在求解的过程中通过子问题的解求出原问题的解。

(7)迭代法

按照一定的规则,不断地用旧值推算出新值,直到满足某种特定条件为止。利用计算机速度快、擅长简单重复的特点,让计算机重复执行若干步骤,并在每次执行这些步骤时,都从旧值算出新值。

(8)分支界限法

把全部可行的解孔家不断分割为越来越小的子集,谓之分支,并为每个子集计算一个下界或上界,谓之定界。在每次分支后,对界限超出已知可行解的子集不再做进一步分支,搜索范围迅速收敛。这一过程一直进行到找出可行解为止,该可行解的值不大于任何子集的界限,因此这种算法一般可以求得全局最优解。

(9)回朔法

在包含问题所有解的解空间树中,从根节点出发,按深度优先搜索解空间树,当搜索到某一节点时,先判断该节点是否包含问题的解,若包含则从节点出发继续搜索,否则逐层向其父节点回溯。若希望求得问题的所有解,则必须回溯到根,且根节点的所有可行子树都必须被搜索到才能结束,否则只要搜索到问题的一个解即可终止。

六、算法的分类

算法按其执行期限可被分为:

(1)有限算法

算法过程无论长短,总能在有限的时间内终止

(2)无限算法

算法过程因无终止条件或终止条件无法得到满足,而永不停息

算法按其解的确定性可被分为:

(1)确定性算法

对于确定的输入,算法总能得到确定的结果

(2)非确定算法

对于确定的输入,算法得到的结果并不唯一确定

七、常见的查找算法

1、线性查找(顺序查找)

(1)算法描述

从头开始,依次将每一个元素与查找目标进行比较,直到找到目标元素,或者与所有元素比较完毕,表示查找失败。

(2)算法评价

平均时间复杂度:O(N)

对数据的有序性没有要求

(3)线性查找实现

编程灵魂——算法

2、二分查找

(1)算法描述

首先假设所有的元素按照升序排列,使用中间元素和目标元素进行比较,如果相等则查找成功,如果中间元素小于目标元素,则去中间元素的右侧查找,否则去中间元素的左侧查找,重复以上过程直到查找成功,或者查找失败。

(2)算法评价

平均时间复杂度:O(logN)

要求样本元素必须有序

(3)基于递归的二分查找实现

编程灵魂——算法

(4)基于循环的二分查找实现

编程灵魂——算法

(5)二分查找说明

编程灵魂——算法

八、常见的排序算法

1、冒泡排序算法

(1)算法描述

相邻元素两两比较,前者大于后者,彼此交换。

从第一对到最后一对,最大的元素沉降到最后。

针对未排序部分,重复以上步骤,沉降次大值。

每次扫描越来越少的元素,直至不再发生交换。

(2)算法评价

平均时间复杂度 O(N^2)

稳定排序,对数据的有序性非常敏感

(3)冒泡排序算法实现

编程灵魂——算法

(4)冒泡排序说明

编程灵魂——算法

2、插入排序算法

(1)算法描述

首元素自然有序

取出下一个元素,对已排序序列,从后向前扫描

大于被取出元素者后移

小于等于被取出元素者,将被取出元素插入其后

重复步骤2,直至处理完所有元素

(2)算法评价

平均时间复杂度 O(N^2)

稳定排序,

对数据的有序性份额长敏感,但是赋值的次数比冒泡排序少,因此略优于冒泡排序算法。

(3)插入排序算法实现

编程灵魂——算法

(4)插入排序说明

编程灵魂——算法

3、选择排序算法

(1)算法描述

在整个序列中寻找最小元素,与首元素交换

在剩余序列中寻找最小元素,与次元素交换

依次类推,知道剩余序列中仅包含一个元素

(2)算法评价

平均时间复杂度:O(N^2)

非稳定排序

对数据的有序性不敏感

交换次数少,优于冒泡排序

(3)选择排序算法实现

编程灵魂——算法

(4)选择排序说明

编程灵魂——算法

原创粉丝点击