python 归并排序的递归法与迭代法(利用队列)实现,以及性能测试
递归排序核心
递归排序的核心是 分与合
分的最终结果 就是将原数组中每一个数字分作一个数组, 合就是 所有小数组不断排序,合并的过程。
合并的过程是先将两个含有一个数字的数组排序,合并(每次比较两个数组的最小值,将更小值加入新数组中,当有一个数组无元素,则将还有元素的数组追加到新数组中即完成排序,合并。新数组已是有序)为一个含有两个元素的有序数组。然后是两个含两个元素的有序数组排序合并为含四个元素的有序数组,两个含四个元素的有序数组合并为含八个元素的有序数组。一直到最终合并为一个数组即完成排序(当然其中有一个小数组可能不是含2的次方个数元素,但处理方式是一样的)。
为什么要用循环迭代实现
我在学归并排序时是先学的递归法实现,在看优化方法时有说到可以用循环迭代的方法实现效率会更高,然后就去了解循环迭代实现归并排序。
然而感觉能搜到的循环迭代法实现感觉不太能理解,至少我在有归并排序的理解在先的情况下看了十几分钟代码还不大懂其中过程。我就想能不能用比较容易理解的方式利用循环迭代实现归并排序。
然后就有了利用队列,用循环迭代的方法完成归并排序。该方法容易理解,也不必考虑些什么递归三要素。并且通过后文的简单的效率分析,能看出处理效率也很好。
循环迭代实现的整体思路
分,平时我们循环一个数组的时候,不就是不断取出其中每一个数字吗,这不是和归并排序中 分 的最终结果如出一辙吗。只要我们将循环中得到每一个数字做成一个含一个数字的数组加入队列中,即可完成分的过程。
合,只要队列中的元素不唯一(队列中每一个元素都是数组哦),不断从队首取出两个数组,排序合并成一个数组,加入到队尾。直至队列元素唯一,最终队列中的唯一数组即是排序好的数组。
搞清楚了整体思路,代码就呼之欲出了。
代码如下:
from _collections import deque
def que_merge(array):
merge_queue = deque()
# 开始分
# 此处是将原列表中元素pop出加入队列,循环结束后原列表会变成只剩一个数字。
# 若不想改变原列表用for循环将每一个数字变为列表加入队列即可。
while len(array) > 1:
# 列表弹出两个列表排序合并,这样进入队列的就直接是含两个数字的有序列表了。当然,不合并直接加入队列也是一样的,并不会影响合的过程。
one = array.pop()
other = array.pop()
if one < other:
merge_list = [one, other]
merge_queue.appendleft(merge_list)
else:
merge_list = [other, one]
merge_queue.appendleft(merge_list)
if array:
merge_queue.appendleft([array.pop()])
# 队列准备就绪,开始排序,合并
while len(merge_queue) > 1:
merge_list1 = merge_queue.pop()
merge_list2 = merge_queue.pop()
l = 0
r = 0
new_li