算法基础

经典算法:

复习算法中……….有不对的地方请指正。

  1. 穷举搜索法:

    描述:穷举搜索算法是对可能是解的众多候选解按照某种顺序进行逐一枚举和检验,并从中找出那些符合要求的候选解作为问题的解。(也就是暴力破解咯+_+)

    注意点:虽然穷举搜索是把所有的可能解都能行枚举和检验,但是并不是杂乱的进行,而是按照某种顺序,使得其不漏掉解,也不重复搜索。当然了常见的肯定是顺序搜索咯。穷举搜索法在面对一些规模特别庞大的问题时有可能不是最优的算法,但却是一种行之有效,并且易于理解的算法;而且在面对规模较小的问题时,其又是一种最为简便高效的算法。

    例如:判断字符串“adbskdjsf”中是否包含字母“j”。

    解:对于这个问题我们应用穷举搜索就需要把字母“j”和字符串中的每一个字符进行比较(从前到后),看是否相等。 也就是按某种顺序(从前到后)把字符串中的每一个元素进行了枚举和检验,最终在其中找到了和“j”相等的字符,也就得到了问题的解。

  1. 迭代算法:

    描述:也称为辗转法,从一个初始估计值出发寻找一系列的近似解来解决问题的一个过程。核心是用一个旧值不断地用迭代公式来得到新值,直到新值和旧值的误差小于给定的误差限为止。常见的有“二分法”,“牛顿法”,“牛顿下山法”等。

    注意点:迭代是用旧值通过迭代公式来不断的推出新值,而递推是利用已解出的小规模问题的解来递推出更大规模问题的解,两者要能区别开

    例如:牛顿迭代法就是典型的利用迭代的算法, xi+1=xif(xi)f(xi) ,从公式中我们可以很清楚的看到,其实用已经得到的旧值 xi ,通过公式来不断的推出新值 xi+1 ,无论 xi 还是 xi+1 ,其都是当前问题的解,只是精确度不同而已,这和后边的递推要能区分开。

  1. 递推算法:

    描述:递推算法是利用本身问题的一种递推关系求解问题的算法。通过把问题分解成若干步,找出相邻几步的关系,从而建立起相邻步骤之间的一种递推关系,进行逐步的求解问题。

    注意点:递推和迭代的异同点:相同的都是逐步的求解出问题的最终解,都是一个不断重复执行一定步骤的算法,不同点是迭代每次是对当前问题的旧解不断迭代产生更加精确,更加近似的新解;而递推是用规模较小的问题的解得到问题规模更大的问题的解,知道递推到当前所求问题规模的解。

  1. 递归算法:

    描述:递归算法是一种直接或者间接调用自身的算法,对于解决一大类的问题十分有效。通常是该问题能分解成规模较小的问题,由这些小问题的解方便的构造出大问题的解,并且这些规模较小的问题也能进一步的采用相同的方法进行分解和综合,特别的,当问题规模小到一定程度时,问题的解能直接得到。

    注意点:递归算法其实就是一系列相似问题的不断分割缩小过程,其更偏向于是一种解决问题的途径或者是工具,常常和其他的算法一同配合使用。在递归算法中要求必须有一个明确的递归结束条件,不然无法结束,而且其在运行时也会很消耗内存,递归次数太多了容易造成堆栈的溢出。

    例如:一个递归的简单例子就是求某个数的阶乘,比如求5的阶乘这个问题,可以逐步的分解成求解5乘以4的阶乘,4乘以3的阶乘,3乘以2的阶乘,2乘以1的阶乘,当分解到1的阶乘时可直接到的结果为1,这就是一个不断“递”的过程,不断的在函数自身中调用自身。然后就需要不断地往回“归”,一层一层的往回走,这样当回到最初的函数中时,问题的解也就得到了。

  1. 分治算法:

    描述:分治算法的思想是把一个复杂的问题分解成若干个互不重合的子问题,通过先求解子问题的解,然后将子问题的解进行合并来得到原问题的解。其核心就是原问题能够分解成和原问题结构相同的子问题,并且子问题的解能合并为原问题的解。

    注意点:分治算法和递归算法都是把原问题不断分解成为若干个比较好解的子问题,通过子问题的解来得到原问题的解,但是不一样的是递归是把问题不断的深入的分解(类似于图的深度优先遍历,是纵向的,我个人的感觉 ………囧…….),而分治算法则像其名字一般,分而治之,把问题分解成若干个平行的子问题(类似于图的广度优先遍历,是很横向的)子问题之间不存在交集,然后把子问题的解进行合并来求解原问题。

    例如:折半查找是典型的分治算法的应用。在一个有序排列的序列中,将n个元素分为个数大致相同的两半,取 a[n2] 元素进行比较。如果x = a[n/2]

  1. 贪心算法:

    描述:贪心算法也称为贪婪算法,其在解决问题时总是做出当前情况下的最优解,而不进行整体的考虑,所以其得到的也是某种意义上的整体最优解,主要是能在范围相当广泛的问题中求解出整体最优解的近似解。

    注意点:贪心算法只考虑眼前,得到的是当前情况下的最优解,但其最后往往也能得到整体最优解的近似解。

    例如:假设有面值为5元,2元,1元,5角,2角,1角的纸币,需要找给顾客4元6角,要求付出的纸币数量最少。则选用贪心算法,首先找出一张面值不超过4元6角的最大面值的纸币,即2元;再选出一张面值不超过2元6角的最大面值的纸币,即2元;再选出一张面值不超过6角的最大面值纸币,即5角;再选出面值不超过1角的最大面值的纸币,即1角。

    在这个过程中总是选择当前最优的解,并不考虑对后一步的影响,所以称之为贪心算法。

  1. 动态规划算法:

    描述:动态规划不是一种具体的算法,是一种在求解问题时的一种途径和思维。其和分治算法很类似,都是将原问题分解成若干个子问题,通过求解子问题来得到原问题的解。

    注意点:动态规划算和分治算法很类似,但与分治算法不同的是,动态规划分解出来的子问题一般都会有重叠,即子问题不是相互独立的。
    若用分治算法,有些子问题就会重复计算,所以一般需要一个记录表,只要是被计算过得子问题的解都会被记录,从而求解时直接进行查表而不是再次进行计算。

  1. 回溯算法:

    描述:回溯算法是一种选优搜索算法,按选优条件向前搜索,直到达到期望的目的。当发现原先的选择并不是最优或者达不到目的时,就进行回退,回退到上一个选择点进行重新选择(不包含已经选择过的路径),直到问题得到解决或者是将所有的选择都进行了尝试。

    注意点:回溯算法会用到辅助的堆栈来保存每一个回溯点,其本质就是进行深度优先的方式对解空间构成的树进行遍历搜索。

    例如:经典的迷宫问题就是回溯算法最典型的应用。

  1. 分支界限算法:

    描述:分支界限算法就如名字一般,确定每一个分支的界限,也就是把问题的解构成的树进行一次广度优先的遍历。把所有可行解空间不断地额分割成更小的解空间(称为子集),并为每个子集内的解计算一个上界和下界(称为定界)在每次分之后对所有界限超过已知可行解的那些子集不在进一步分支(应用最大收益或者是最小损耗策略来控制搜索的分支数),直到求解出可行解的值不大于任何子集的界限为止。

    注意点:分支界限不是对所有的分支都会进行下一步的分解,而是在每一分解后都会进行有条件的筛选,以减少搜索的数量,以提高效率。

你可能感兴趣的:(数据结构,算法)