堆排序和归并排序以及快速排序是比较经典的排序方法。堆排序的时间复杂度是nlogn,归并排序的时间复杂度可以达到O(n),快速排序的时间复杂度是nlogn。可见归并排序的排序速度比较快,但是比较耗费内存,毕竟是通过递归的方式来切分待排序序列。
堆排序可以参考我的上一篇博客。归并排序从字面意思来看,有两个过程:“归”和“并”。“归”是递归的意思,“并”当然是合并的意思。
“归”。递归是归并排序的核心思想。其基本思想是对于一个无序的序列我们总是可以将它一分为二。直到切分出来的序列有序。按照这个分法,我们总可以通过有限步的切分,将待排序序列切分成若干个有序的子序列。然后通过递归的逆过程,将切分出来的有序子序列进行合并。下面给出一个例子:
对序列 sequence = [9, 5 , 7, 2]进行归并排序。序列切分方法:left = len(sequence ) // 2
1、left_sequence = [9, 5] right_sequence = [7, 2]
显然left_sequence 是没有顺序的,需要按照上面的方法继续进行切分。
2、left_sequence_1 = [9] right_sequence_1 = [5]
显然 left_sequence_1 和 right_sequence_1 都是有顺序的序列。我们不再对其进行切分
3、left_sequence_2 = [7] right_sequence_2 = [2]
显然 left_sequence_2 和 right_sequence_2 都是有顺序的序列。我们不再对其进行切分
通过这3步,递归过程就完成了。
“并”。递归的逆过程。通过上面的例子,我们可以很清楚的看到总共切分除了4个子序列。将 left_sequence_2 和 right_sequence_2进行合并。这里需要提一下,合并的方法有很多。最有效的方法可能就是下面的这种形式:
while left_index < len(left_sequence_2):
right_sequence_2.append[right_sequence_2[0]] # 从上个序列取出的元素必须要放到第二个序列中。
while right_index < len(right_sequence_2) - 1: # 减1,sequence_2最后一个元素不需要比较
if right_sequence_2[right_index] < left_sequence_2[left_index]:
right_index += 1
else: