归并排序和快速排序均是利用分治策略的递归排序算法。
下面是归并排序的Python实现:
def mergesort(array):
N = len(array)
_msort(array, 0, N - 1)
def _msort(array, left, right):
if left < right:
center = (left + right) // 2
_msort(array, left, center)
_msort(array, center + 1, right)
_merge(array, left, center + 1, right)
def _merge(array, left, right, rightend):
leftend = right - 1
temp = array[:]
tidx = left
N = rightend - left + 1
while left <= leftend and right <= rightend:
if array[left] < array[right]:
temp[tidx] = array[left]
left += 1
else:
temp[tidx] = array[right]
right += 1
tidx += 1
while left <= leftend:
temp[tidx] = array[left]
left += 1
tidx += 1
while right <= rightend:
temp[tidx] = array[right]
right += 1
tidx += 1
for i in range(0, N):
array[rightend - i] = temp[rightend - i]
def test():
array = [24, 13, 26, 1, 2, 27, 38, 15]
correct_array = [1, 2, 13, 15, 24, 26, 27, 38]
mergesort(array)
if array == correct_array:
print 'test passed. \nsorted array: %s' % array
else:
print 'test failed. \nsorted array: %s' % array
if __name__ == '__main__':
test()
下面是快速排序的Python实现:
def quicksort(array, cutoff = 5):
N = len(array)
_qsort(array, 0, N - 1, cutoff)
def insertionsort(array):
N = len(array)
_insertionsort(array, 0, N)
def _qsort(array, left, right, cutoff):
if left + cutoff <= right:
pivot = _median3(array, left, right)
i = left
j = right - 2
while True:
while array[i] < pivot:
i += 1
while array[j] > pivot:
j -= 1
if i < j:
_swap(array, i, j)
else:
break
_swap(array, i, right - 1)
_qsort(array, left, i - 1)
_qsort(array, i + 1, right)
else:
_insertionsort(array, left, right - left + 1)
def _insertionsort(array, left, N):
for i in range(left + 1, left + N):
tmp = array[i]
j = i
for j in range(i - 1, left - 1, -1):
if array[j] > tmp:
array[j + 1] = array[j]
# the following statement is used when this loop is finished by
# the terminal condition not the break statement.
if j == left: j -= 1
else:
break
array[j + 1] = tmp
def _median3(array, left, right):
center = (right + left) // 2
if array[left] > array[center]:
_swap(array, left, center)
if array[left] > array[right]:
_swap(array, left, right)
if array[center] > array[right]:
_swap(array, center, right)
_swap(array, center, right - 1)
return array[right - 1]
def _swap(array, ia, ib):
array[ia] = array[ia] + array[ib]
array[ib] = array[ia] - array[ib]
array[ia] = array[ia] - array[ib]
def test():
array = [81, 13, 92, 43, 65, 31, 57, 26, 75, 0]
correct_array = [0, 13, 26, 31, 43, 57, 65, 75, 81, 92]
quicksort(array)
if array == correct_array:
print 'test passed.', array
else:
print 'test failed.', array
if __name__ == '__main__':
test()
快速排序的实现,的确很容易就写错,导致最后排序结果不正确。
其中对于小数组使用的cutoff range默认取5,并且在使用插入排序时,必须注意的一点是,当第2层循环结束是由于循环终止条件而不是break语句时,必须有相应的处理语句,以避免排序结果出现第二个元素是最小元素的情形。