支持重複元素,理解容易,但不是原地排序方法.
代碼參上
# -*- coding:utf-8 -*-
def quick_sort(list_o):
# 不可能發生的情況
if len(list_o) == 0 or list_o is None:
print("enter len 0!!it's impossile!")
return list([])
# 子列表長度爲1
elif len(list_o) == 1:
return list_o
# 子列表長度爲2
elif len(list_o) == 2:
if list_o[0] > list_o[1]:
list_o.reverse()
return list_o
# 子列表長度>=3
else:
# 針對很多元素重複,去重後只有2個不同元素的情況
if len(set(list_o)) == 2:
# 使用最大值最爲分割
bigger = max(set(list_o))
# 針對最大值也有多個的情況
bigger_count = list_o.count(bigger)
# 將最大的元數移動到列隊尾部
for i in range(bigger_count):
bigger_index = list_o.index(bigger)
should_be_index = len(list_o)-i-1
if bigger_index != should_be_index:
list_o[bigger_index], list_o[should_be_index] = list_o[should_be_index], list_o[bigger_index]
return list_o
# 針對很多元素重複,去重後只有1個不同元素的情況
elif len(set(list_o)) == 1:
return list_o
# 去重後大於等於3個不同元素的子列表
else:
# 嘗試取中間的元素作爲分割
split_elem_id = int(len(list_o)/2)
# 當分割元素是該子列表的最大值或者最小值時,換一個元素做分割,避免子列表無法繼續分割的情況發生
while list_o[split_elem_id] == max(list_o) or list_o[split_elem_id] == min(list_o):
split_elem_id -= 1
left_list = []
right_list = []
split_elem = list_o[split_elem_id]
print("split element is %s" % split_elem)
# 進行分割
for i in list_o:
if i <= split_elem:
left_list.append(i)
else:
right_list.append(i)
print("left is {left_list},right is {right_list}".format(left_list=left_list, right_list=right_list))
# 遞歸排序併合並子列表
return quick_sort(left_list)+[split_elem]+quick_sort(right_list)
if __name__ == "__main__":
a = [1,3,45,65,21,12,2,2,78,54,56,23]
b = quick_sort(a)
print b
print "-----------------------------------------------"
aa = [1,11,1,1,1,1,1,1,1,1,1,11,1,1,1,1,1,1,11,11]
bb = quick_sort(aa)
print bb
print "-----------------------------------------------"
aaa = [0,0,0,0,0,0,2,2,2,2,2,1,1,1,1,1,1]
bbb = quick_sort(aaa)
print bbb
print "-----------------------------------------------"
ss = ["aa", "a", "a","aa", "aaa","b","f","e"]
ssbb = quick_sort(ss)
print(ssbb)
運行一下:
C:\Python27\python.exe D:/代碼/python-DP/QuickSort.py
split element is 2
left is [1, 2, 2],right is [3, 45, 65, 21, 12, 78, 54, 56, 23]
split element is 12
left is [3, 12],right is [45, 65, 21, 78, 54, 56, 23]
split element is 65
left is [45, 65, 21, 54, 56, 23],right is [78]
split element is 54
left is [45, 21, 54, 23],right is [65, 56]
split element is 45
left is [45, 21, 23],right is [54]
split element is 23
left is [21, 23],right is [45]
[1, 2, 2, 2, 3, 12, 12, 21, 23, 23, 45, 45, 54, 54, 56, 65, 65, 78]
-----------------------------------------------
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 11, 11, 11]
-----------------------------------------------
split element is 1
left is [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],right is [2, 2, 2, 2, 2]
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2]
-----------------------------------------------
split element is aaa
left is ['aa', 'a', 'a', 'aa', 'aaa'],right is ['b', 'f', 'e']
split element is aa
left is ['aa', 'a', 'a', 'aa'],right is ['aaa']
split element is e
left is ['b', 'e'],right is ['f']
['a', 'a', 'aa', 'aa', 'aa', 'aaa', 'aaa', 'b', 'e', 'e', 'f']
Process finished with exit code 0