接上文
你可能已经发现了,merge(A[p...r], A[p...q], A[q+1...r])
这个函数的作用就是,将已经有序的 A[p...q]
和 A[q+1....r]
合并成一个有序的数组,并且放入 A[p....r]
。那这个过程具体该如何做呢?
如图所示,我们申请一个临时数组 tmp
,大小与 A[p...r]
相同。我们用两个游标 i
和 j
,分别指向 A[p...q]
和 A[q+1...r]
的第一个元素。比较这两个元素 A[i]
和 A[j]
,如果 A[i]<=A[j]
,我们就把 A[i]
放入到临时数组 tmp
,并且 i
后移一位,否则将 A[j]
放入到数组 tmp
,j 后移一位。
继续上述比较过程,直到其中一个子数组中的所有数据都放入临时数组中,再把另一个数组中的数据依次加入到临时数组的末尾,这个时候,临时数组中存储的就是两个子数组合并之后的结果了。最后再把临时数组 tmp
中的数据拷贝到原数组 A[p...r]
中。
我们把 merge() 函数写成伪代码,就是下面这样:
def merge(a, b):
c = [] # 临时数组
j = h = 0
# 两个有序数组排序的方法则非常简单,同时对两个数组的第一个位置进行比大小,
# 将小的放入一个空数组,然后被放入空数组的那个位置的指针往后 移一个,然后继续和另外一个数组的上一个位置进行比较
while j < len(a) and h < len(b):
if a[j] < b[h]:
c.append(a[j])
j = j + 1
else:
c.append(b[h])
h = h + 1
# 最后任何一个数组先出栈完,就将另外i一个数组里的所有元素追加到新数组后面。
if j == len(a):
for i in b[h:]:
c.append(i)
else:
for i in a[j:]:
c.append(i)
return c
def mergesort(arr):
if len(arr) <= 1:
return arr
middle = len(arr) // 2 ## 拆分列表
left = mergesort(arr[:middle]) # 左半部分排序
right = mergesort(arr[middle:]) # 右半部分排序
return merge(left, right) # 合并逻辑
arr = [4, 7, 8, 3, 5, 9, 6]
print(mergesort(arr))
总结
- 合并的方法是借助
两个游标
,分别指示每个数组的开始 - 两个开始位置相互比较,较小的放入临时数组,同时游标右移