快速排序采用分治的思想,是对冒泡排序的一种改进。首先在数组中选取一个数作为pivotkey,将比其小的放在左边,比其大的放在右边,然后对左右两边分别调用快速排序。但是其实现过程有很多种方法,分为两个要点,其一是如何选择pivotkey,可以随机选择、选择两个不同数值中较大的那个或选择首位、中位、末位三者之间的中位数等;其二是如何对数组进行划分,可以从头至尾扫描,将小于中位数的元素与大于中位数的元素交换位置或分别从头至尾扫描小于中位数的、从尾至头扫描大于中位数的,将不满足要求的交换位置即可。
快速排序是不稳定的,其最坏时间复杂度为O(n2),即在数组已经排好序的情况下,每次划分均在中间的位置,;最好时间复杂度为O(nlogn),是标准的分治算法。通常情况下接近于最好时间复杂度。
def QuickSort1(a):
if len(a) <= 1:
return a
flag,index = -1,0
pivotkey = a[len(a)-1]
for i in range(len(a)-1):
if a[i] > pivotkey:
flag = i
else:
index = i+1
if flag >= 0:
index = flag+1
a[i],a[flag] = a[flag],a[i]
flag = i
a[index], a[len(a)-1] = a[len(a)-1], a[index]
return QuickSort1(a[0:index]) + QuickSort1(a[index:len(a)])
def QuickSort2(a):
if len(a) <= 1:
return a
if a[1] > a[0]:
pivotkey = a[1]
a[1], a[len(a)-1] = a[len(a)-1],a[1]
else:
pivotkey = a[0]
a[0], a[len(a)-1] = a[len(a)-1],a[0],
i = 0; j = len(a)-2
flag1,flag2 = 0,0
while i <= j:
if flag1 and flag2:
a[i],a[j] = a[j],a[i]
flag1,flag2 = 0,0
if a[i] <= pivotkey:
i = i+1
else:
flag1 = 1
if a[j] > pivotkey:
j = j-1
else:
flag2 = 1
a[i],a[len(a)-1] = a[len(a)-1],a[i]
return QuickSort2(a[0:i]) + QuickSort2(a[i:len(a)])
if __name__ == '__main__':
a = [1, 7, 3, 9, 14, 2, 5, 9, 6, 10]
b = QuickSort1(a.copy())
c = QuickSort1(a.copy())
print(b)
print(c)