📅  最后修改于: 2023-12-03 15:13:08.473000             🧑  作者: Mango
3路合并排序指的是将一个待排序的序列(长度为N)分成3个子序列,分别对这3个子序列进行排序,然后将3个有序的子序列合并成一个有序的序列。这是一种归并排序的变种。
算法分为两部分:
def merge(arr, l, m1, m2, r):
left = arr[l:m1+1]
middle = arr[m1+1:m2+1]
right = arr[m2+1:r+1]
i = j = k = 0
while i < len(left) and j < len(middle) and k < len(right):
if left[i] <= middle[j] and left[i] <= right[k]:
arr[l] = left[i]
i += 1
elif middle[j] <= left[i] and middle[j] <= right[k]:
arr[l] = middle[j]
j += 1
else:
arr[l] = right[k]
k += 1
l += 1
while i < len(left):
arr[l] = left[i]
i += 1
l += 1
while j < len(middle):
arr[l] = middle[j]
j += 1
l += 1
while k < len(right):
arr[l] = right[k]
k += 1
l += 1
def three_way_merge_sort(arr, l, r):
if l < r:
m1 = l + (r - l) // 3
m2 = l + 2 * ((r - l) // 3)
three_way_merge_sort(arr, l, m1)
three_way_merge_sort(arr, m1+1, m2)
three_way_merge_sort(arr, m2+1, r)
merge(arr, l, m1, m2, r)
使用迭代的方法实现3路合并排序。
def three_way_merge_sort(arr, l, r):
if l >= r:
return
k = (r - l) // 3 + 1
for i in range(k):
three_way_merge_sort(arr, l+i*(r-l)//3, l+(i+1)*(r-l)//3-1)
while k > 1:
for i in range(0, k-2, 2):
merge(arr, l+i*(r-l)//3, l+(i+2)*(r-l)//3-1, l+(i+3)*(r-l)//3-1, l+(i+4)*(r-l)//3-1)
if k % 2 == 0:
merge(arr, l, l+(k-2)*(r-l)//3, l+k*(r-l)//3-1, r)
else:
merge(arr, l, l+(k-3)*(r-l)//3, l+(k-1)*(r-l)//3-1, r)
k = (k+1) // 2
3路合并排序的时间复杂度与归并排序一致,即O(N * logN)。但是,由于归并的过程中,需要额外的空间来存储每个子序列。所以空间复杂度要比归并排序大一些。但是,由于它分成了三个子序列,所以在处理一些大数据的时候,它的性能比其他归并排序要好一些。