快速排序法的原理
对于一乱序数组,进行排序,排序过程:
任取一位作为flag(比较位),比它小的在左边,比它大的在右边,这样的操作为一轮快速排序;对flag两边的序列分别执行
同样的操作,n轮后,数组有序;
对于每一轮快速排序,又可细化为如下过程:
- 对于待处理序列A,有序列长度为length,赋索引 i = 0 ,j = length -1, 取序列第一个元素作为flag, flag = A[0];
- 从右边寻找比flag小的数,若寻到则A[0] 与 A[ j ]值互换,跳转3操作;若寻不到,j自减1,直到寻到或者直到 j == i ;
- 从左边寻找比flag大的数,若寻到则A[0] 与 A[ i ]值互换,跳转2操作;若寻不到,i自加1,直到寻到或者直到 j == i ;
排序过程示例
--------------------------------------------------
对原序列进行排序A
flag: 43
排序前: [43, 33, 35, 29, 42, 16, 2, 12, 34, 26, 17, 6, 45, 216, 1]
i=1,j=14
s: [1, 33, 35, 29, 42, 16, 2, 12, 34, 26, 17, 6, 45, 216, 43]
i=12,j=13
b: [1, 33, 35, 29, 42, 16, 2, 12, 34, 26, 17, 6, 43, 216, 45]
对43左边的序列进行快速排序A-L
flag: 1
排序前: [1, 33, 35, 29, 42, 16, 2, 12, 34, 26, 17, 6]
对于1右边的序列进行排序A-L-R
flag: 33
排序前: [33, 35, 29, 42, 16, 2, 12, 34, 26, 17, 6]
i=1,j=10
s: [6, 35, 29, 42, 16, 2, 12, 34, 26, 17, 33]
i=1,j=9
b: [6, 33, 29, 42, 16, 2, 12, 34, 26, 17, 35]
i=2,j=9
s: [6, 17, 29, 42, 16, 2, 12, 34, 26, 33, 35]
i=3,j=8
b: [6, 17, 29, 33, 16, 2, 12, 34, 26, 42, 35]
i=4,j=8
s: [6, 17, 29, 26, 16, 2, 12, 34, 33, 42, 35]
i=7,j=7
b: [6, 17, 29, 26, 16, 2, 12, 33, 34, 42, 35]
对33左边的序列进行排序A-L-R-L
flag: 6
排序前: [6, 17, 29, 26, 16, 2, 12]
i=1,j=5
s: [2, 17, 29, 26, 16, 6, 12]
i=1,j=4
b: [2, 6, 29, 26, 16, 17, 12]
剩下的自己推下去:.....
flag: 29
排序前: [29, 26, 16, 17, 12]
i=1,j=4
s: [12, 26, 16, 17, 29]
flag: 12
排序前: [12, 26, 16, 17]
flag: 26
排序前: [26, 16, 17]
i=1,j=2
s: [17, 16, 26]
flag: 17
排序前: [17, 16]
i=1,j=1
s: [16, 17]
flag: 34
排序前: [34, 42, 35]
flag: 42
排序前: [42, 35]
i=1,j=1
s: [35, 42]
flag: 216
排序前: [216, 45]
i=1,j=1
s: [45, 216]
--------------------------------------------------
排序前: [43, 33, 35, 29, 42, 16, 2, 12, 34, 26, 17, 6, 45, 216, 1]
排序后: [1, 2, 6, 12, 16, 17, 26, 29, 33, 34, 35, 42, 43, 45, 216]
代码实现
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 12 10:44:54 2018
Description:
Version:
@author: HJY
"""
import random
import copy
def quick_sort(base):
if len(base) < 2:
return base
i = 0
j = len(base)-1
flag = base[0]
print(flag)
print('c:',base)
#一轮快速排序,完成两边分布#############################
while not(i==j):
while not(i==j):
if base[j] < flag:
base[j],base[i] = base[i],base[j]
i+=1
print(i,j)
print('s:',base)
break
else:
j-=1
while not(i==j):
if base[i] > flag:
base[i],base[j] = base[j],base[i]
j-=1
print(i,j)
print('b:',base)
break
else:
i+=1
#####################################################
return quick_sort(base[:i]) + [base[i]] + quick_sort(base[i+1:])
base = [random.randint(1,50) for _ in range(15)]
#base = [43, 33, 35, 29, 43, 16, 2, 12, 34, 2, 16, 1, 43, 26, 1]
do = copy.deepcopy(base)
print('-'*50)
do = quick_sort(do)
print('-'*50)
print('排序前:',base)
print('排序后:',do)
执行前一篇记录(冒泡排序法与鸡尾酒排序法),进行时间性能的对比(序列长度为1000):
可以看到快速排序的算法性能远远优于两种