如何在 Python 中实现双轴快速排序
how to implement dual-pivot quicksort in Python
所以我一直在尝试在 Python 2.7 中重现双轴快速排序算法;最基本的 运行 完美:
def quicksort_by_length(list, start, top):
if top <= start:
return
p = start
k = start+1
h = k
while k <= top:
if list[k] < list[p]:
list[k], list[h] = list[h], list[k]
h += 1
k += 1
h -= 1
list[p], list[h] = list[h], list[p]
quicksort_by_length(list, start, h-1)
quicksort_by_length(list, h+1, top)
接下来,我转向双枢轴,这是我尝试过的:
def dual_pivot_sort(list, start, top):
if top <= start:
return
p = start
q = top
k = p+1
h = k
l = q-1
if list[p] > list[q]:
list[p], list[q] = list[q], list[p]
while k < top:
if list[k] < list[p]:
list[h], list[k] = list[k], list[h]
h += 1
elif list[k] > list[q]:
list[k], list[l] = list[l], list[k]
l -= 1
k += 1
h -= 1
l += 1
list[p], list[h] = list[h], list[p]
list[q], list[l] = list[l], list[q]
dual_pivot_sort(list, start, h-1)
dual_pivot_sort(list, h+1, l-1)
dual_pivot_sort(list, l+1, top)
在尝试几个列表时,此代码可以对反向列表进行排序,但无法处理 运行dom 或先升后降列表:尝试对 [1, 2, 3, 4, 5 , 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1] 给出 [1, 1, 2, 3, 4, 5, 5, 6, 3, 4, 7, 2 , 6, 7, 8, 8, 9]。我缺少什么简单的东西吗?
def dual_pivot_sort(list, start, top):
if top <= start:
return
p = start
q = top
k = p+1
h = k
l = q-1
if list[p] > list[q]:
list[p], list[q] = list[q], list[p]
while k <= l:
# the last non-check index is l,as l+1 to top - 1 is the part III,
#where all elements > list[top]
if list[k] < list[p]:
list[h], list[k] = list[k], list[h]
#h is the first element of part II
h += 1
#increase h by 1, for pointing to the first element of part II
k += 1
#increase k by 1, because we have checked list[k]
elif list[k] > list[q]:
#l is the last element of part IV
list[k], list[l] = list[l], list[k]
#don't increase k, as we have not check list[l] yet
l -= 1
#after swap, we should compare list[k] with list[p] and list[q] again
else: k += 1
# no swap, then the current k-th value is in part II, thus we plus 1 to k
h -= 1#now,h is the last element of part I
l += 1 #now, l is the first element of part III
list[p], list[h] = list[h], list[p]
list[q], list[l] = list[l], list[q]
dual_pivot_sort(list, start, h-1)
dual_pivot_sort(list, h+1, l-1)
dual_pivot_sort(list, l+1, top)
II/III部分的定义和双轴排序的解释可以参考What's the difference of dual pivot quick sort and quick sort?
所以我一直在尝试在 Python 2.7 中重现双轴快速排序算法;最基本的 运行 完美:
def quicksort_by_length(list, start, top):
if top <= start:
return
p = start
k = start+1
h = k
while k <= top:
if list[k] < list[p]:
list[k], list[h] = list[h], list[k]
h += 1
k += 1
h -= 1
list[p], list[h] = list[h], list[p]
quicksort_by_length(list, start, h-1)
quicksort_by_length(list, h+1, top)
接下来,我转向双枢轴,这是我尝试过的:
def dual_pivot_sort(list, start, top):
if top <= start:
return
p = start
q = top
k = p+1
h = k
l = q-1
if list[p] > list[q]:
list[p], list[q] = list[q], list[p]
while k < top:
if list[k] < list[p]:
list[h], list[k] = list[k], list[h]
h += 1
elif list[k] > list[q]:
list[k], list[l] = list[l], list[k]
l -= 1
k += 1
h -= 1
l += 1
list[p], list[h] = list[h], list[p]
list[q], list[l] = list[l], list[q]
dual_pivot_sort(list, start, h-1)
dual_pivot_sort(list, h+1, l-1)
dual_pivot_sort(list, l+1, top)
在尝试几个列表时,此代码可以对反向列表进行排序,但无法处理 运行dom 或先升后降列表:尝试对 [1, 2, 3, 4, 5 , 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1] 给出 [1, 1, 2, 3, 4, 5, 5, 6, 3, 4, 7, 2 , 6, 7, 8, 8, 9]。我缺少什么简单的东西吗?
def dual_pivot_sort(list, start, top):
if top <= start:
return
p = start
q = top
k = p+1
h = k
l = q-1
if list[p] > list[q]:
list[p], list[q] = list[q], list[p]
while k <= l:
# the last non-check index is l,as l+1 to top - 1 is the part III,
#where all elements > list[top]
if list[k] < list[p]:
list[h], list[k] = list[k], list[h]
#h is the first element of part II
h += 1
#increase h by 1, for pointing to the first element of part II
k += 1
#increase k by 1, because we have checked list[k]
elif list[k] > list[q]:
#l is the last element of part IV
list[k], list[l] = list[l], list[k]
#don't increase k, as we have not check list[l] yet
l -= 1
#after swap, we should compare list[k] with list[p] and list[q] again
else: k += 1
# no swap, then the current k-th value is in part II, thus we plus 1 to k
h -= 1#now,h is the last element of part I
l += 1 #now, l is the first element of part III
list[p], list[h] = list[h], list[p]
list[q], list[l] = list[l], list[q]
dual_pivot_sort(list, start, h-1)
dual_pivot_sort(list, h+1, l-1)
dual_pivot_sort(list, l+1, top)
II/III部分的定义和双轴排序的解释可以参考What's the difference of dual pivot quick sort and quick sort?