几种常用算法思考

    算法是解决问题的方法和思路。各个领域的算法是非常多的,然而总有一些各个领域通用的算法值得大家学习和研究,通过学习这些经典的思路我们可以触类旁通衍生出其他一些解决问题的算法套路。比如递归,回溯,动态规划,贪心法,排序,查找,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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贪心算法是一种常用的求解最优化问题的方法,它通过每一步选择当前最优的解来逐步构建整体最优解。而哈夫曼编码是一种用于数据压缩的编码方式,它通过将出现频率较高的字符用较短的编码表示,从而实现对数据的高效压缩。 在使用贪心算法求解哈夫曼编码时,我们首先需要统计字符出现的频率,并根据频率构建一个优先队列(通常使用最小堆实现)。然后,我们每次从队列中选择频率最低的两个字符,将它们合并为一个新的节点,并将新节点的频率设置为两个字符频率之和。这个新节点再次加入到队列中,重复上述步骤,直到队列中只剩下一个节点为止。 通过这种方式,我们可以构建出一棵哈夫曼树,树的叶子节点对应着字符,而根节点到叶子节点的路径上的编码就是对应字符的哈夫曼编码。由于每次选择频率最低的两个字符进行合并,所以贪心算法保证了构建出来的哈夫曼树是最优的。 在实际应用中,贪心算法求解哈夫曼编码具有以下几个优点: 1. 哈夫曼编码可以实现无损压缩,即解码后的数据与原始数据完全一致。 2. 哈夫曼编码可以根据字符出现的频率来分配不同长度的编码,从而实现对频率较高的字符进行更高效的压缩。 3. 哈夫曼编码可以根据字符的出现频率构建出一棵唯一确定的哈夫曼树,从而实现编码和解码的一致性。 然而,贪心算法求解哈夫曼编码也存在一些限制和注意事项: 1. 贪心算法只能保证局部最优解,不能保证全局最优解。因此,在实际应用中,需要根据具体问题进行合理的设计和调整。 2. 贪心算法求解哈夫曼编码的时间复杂度为O(nlogn),其中n为字符的个数。因此,在处理大规模数据时,需要考虑算法的效率和性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值