“自顶向下,逐步求精”在算法中的应用

“自顶向下,逐步求精”在算法中的应用

“自顶向下,逐步求精”其实是一个很简单的概念,总的来说,就一句话:“将大问题分解为小问题”。
在这里,介绍一个利用“自顶向下,逐步求精”的算法:归并排序。

各位看官不要看到“归并”之类的算法名称就跑了,其实这是非常非常简单的而且便于理解的算法。
我们在VMatrix上面做过这一个题:

Merging Lists

Description
Write the following function that merges two sorted lists into a new sorted list:
void merge(const int list1[], int size1, const int list2[], int size2, int list3[])
where list1 and list2 are sorted non-decreasingly, size1 and size2 are the numbers of integers in list1 and size2, respectively. For example, suppose list1 is {1, 5, 16, 61, 111}, and list2 is {2, 4, 5, 6}. After invoking merge(list1, 5, list2, 4, list3), list3 is {1, 2, 4, 5, 5, 6, 16, 61, 111}.

由于这是程序设计(I)的作业,现在我们假设大家都已经会做这道题了,此处不放题解。我们要解决的是另外一道题,这道题的描述比上面这道简单得多:

将一个无序数组排序。

那么这是一个大家都耳熟能详的问题了,我们已经知道冒泡排序法和选择排序法。但是,这两种方法效率太低了。我们能否用到“自顶向下,逐步求精”的方法呢?

实际上是可以的。我们要得到一个有序的数列,只要将两个有序的数列合并为一个就可以了。

这两个有序的数列从哪里来?分别再用两个有序的数列合并为一个就可以了。

这四个有序的数列从哪里来?分别再用两个有序的数列合并为一个就可以了。

这八个有序的数列从哪里来?分别再用两个有序的数列合并为一个就可以了。

…………

如此循环往复,只到分解为只剩下一个数为止。此时有序的数列显然就是这一个数了,那么就可以开始合并,最终真正得到一个有序的数列。

理论上说,将一个数列分割,可以从任意点分割开。但是如果将分割点放在开头,则与冒泡排序无异,失去其优势。所以我们通常将分割点放在数列中间,此时该算法的时间复杂度即为O(n log n)(算法中,log 的底数为2,与数学中的 lg 不同)。

事实上,“自顶向下,逐步求精”在算法中的应用非常广泛,通常被称为“分治法”。分治法是其它很多算法的基础。算法是一个很奇妙的东西,值得好好研究。

感谢你看到这里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值