几种常用算法思考

来源:互联网 发布:mysql分布式数据库搭建 编辑:程序博客网 时间:2024/06/11 15:53

    算法是解决问题的方法和思路。各个领域的算法是非常多的,然而总有一些各个领域通用的算法值得大家学习和研究,通过学习这些经典的思路我们可以触类旁通衍生出其他一些解决问题的算法套路。比如递归,回溯,动态规划,贪心法,排序,查找,hash等等。还有一些经典的数据结构,比如树(二叉树,AVL树,红黑树,B树等),图。 有些算法是针对特定数据结构的(比如针对图的dijkstra算法,最短路径算法),有些算法却只提供思路,并不针对特定的数据结构(比如递归)。

    我想最经典和最常用的算法就是递归了。递归算法可能和树这种结构太紧密了, 递归所解决的问题域有相似的地方,比如一棵二叉树的遍历,二叉树本身就有相似的地方,每一个子节点可以做为一棵新树的根节点,这个形式就决定了它很容易用上递归的思想。简单来讲,递归的思想就是把问题划分成更小的问题,而更小的问题和大的问题解法完全相同,然后不断缩小收敛,直到问题简单到手工就能解决。我们高中时学过一种证明自然数的数学题的方法叫数学归纳法,它其实就是利用的递归思想,先证明n=1的时候成立,这就是递归的收敛点,再假设n=k时成立,证明n=k+1也成立,就证毕了。递归其实就是把问题不断的缩小,值域缩小,但是问题的形式不变。我们经典的递归问题就是非波拉契数列了:

f(1) = 1, f(2)=1, f(n) = f(n-1) +f(n-2) 当n>=3时。 用c代码就是

long fib(int n)

{

    if(n ==1) return 1;

   if(n==2 )return 1;

   return fib(n-1) + fib(n-2);

}

递归的思想很重要,甚至在快速排序中也用到了递归的思想:选出一个中位数,把序列分成两列,前者序列都比中位数小,后者都比中位数大。那么中位数的位置就固定了,然后呢?前者和后者有都成了相同的问题了,只是求解域不断的变小,直到收敛到最小(1)。

同样,二分查找中也运用了递归思想:找中位数,如果中位数是目标点就返回。否则,如果比中位数大就在右边子序列中查找,如果比中位数小就在左序列中查找。问题就是这样化成一个个完全相同的子问题,只是求解域再不断缩小。

    有些问题如果不用递归去解决,真的很难甚至不可能。比如:对一棵树的遍历,其实不用递归也可以,借助一个栈来缓存中间遍历结果,但是用递归,代码相当简洁,可读性也很好。再比如浏览器里的排版,dom树和render树的生成,如果不用递归,代码将非常难于理解。

    回溯法呢?其实我觉得回溯法不是一种特别说的清楚的算法,只是不断的尝试回退,有点暴力的感觉。但是也可以用到递归的思想,因为每次回溯,问题又变成一样的了,求解域可能没有变小,但是逼近正确了。至少排除了一些错误的尝试。

动态规划法呢,其实就是暴力求解的思路,只是因为暴力求解中计算的中间过程可以重复利用,我们就保存下来,空间换时间,其实还是遍历了所有可能性,属于暴力求解的改进方案:经典的如01背包问题。

树这个结构在查找遍历里面很常用,比如平衡二叉树,红黑树,以及B树(B+树)等,都是为了把查找缩短在lgN的时间复杂度上。所以关于树的一些算法也很多。

0 0
原创粉丝点击