-
什么是快速排序?
快速排序是一个既高效又不浪费空间的一种排序算法。首先我们需要设定中心轴,将大于中心轴的数据放在中心轴的左边,小于中心轴的数据放在中心轴的右边。 -
快速排序的排序流程
所以,我们需要设定中心轴以及左右两边两个指针。这里设定为L以及R。
例如一个列表[12,45,65,43,54,10,76,]
我们设定中心轴为该列表的第一个数字,L为该排序列表右开头,R为该数据列表左开头。即:
a = [12,45,65,43,54,10,76]
p = a[0]
L = 0
R = len(a)-1
我们将左边作为中心轴,所以我们R指针应该先行运行。但是问题来了?它应该走多少次呢?实际上我们是不知道运行次数的,但是我们知道什么时候R指针停止运行。
a = [12,45,65,43,54,10,76]
p = a[0]
L = 0
R = len(a)-1
while a[R]>=p:
R-=1
print(R)#测试一下
当R寻找到对应的较小的数据的时候,需要L开始运行。L的运行实际上也是和R类似的
a = [12,45,65,43,54,10,76]
p = a[0]
L = 0
R = len(a)-1
while a[R]>=p:
R-=1
while a[L]<=p:
L+=1
print(L)#测试一下
这个时候我们需要将L和R对应的数据交换,以确保较大数字在右,较小数字在左。
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
a = [12,45,65,43,54,10,76]
p = a[0]
L = 0
R = len(a)-1
while a[R]>=p:
R-=1
while a[L]<=p:
L+=1
print(L)#测试一下
swap(b,c)
当L运行完一次后。L值为2,R值为5。
紧接着,我们的L和R还需要继续走一轮即
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
a = [12,45,65,43,54,10,76]
p = a[0]
L = 0
R = len(a)-1
while a[R]>=p:
R-=1
while a[L]<=p:
L+=1
swap(b,c)
while a[R]>=p:
R-=1
while a[L]<=p:
L+=1
在本轮运行完后,其实我们会发现L数值为2,R的数值为1.出现了交叉现象,L>R,L将R走过的数据重新走过了,所以我们需要添加条件并优化代码
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
a = [12,45,65,43,54,10,76]
p = a[0]
L = 0
R = len(a)-1
while L<R:
while a[R]>=p and L<R:
R-=1
while a[L]<=p and L<R:
L+=1
swap(b,c)
还需要添加一段代码实现中心轴和L或者R交换!
所以:
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
a = [12,45,65,43,54,10,76]
p = a[0]
p_b =0
L = 0
R = len(a)-1
while L<R:
while a[R]>=p and L<R:
R-=1
while a[L]<=p and L<R:
L+=1
swap(b,c)
swap(L,p_b)
到这里我们实现了一轮排序,但是后续我们需要对左右子序列进行排序,而实现排序的代码和我们先前制作的毫无区别。所以我们可以将对应的代码变成函数!
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
a = [12,45,65,43,54,10,76]
def paixu(pL,pR):
p = a[pL]
L = pL
R = pR
while L<R:
while a[R]>=p and L<R:
R-=1
while a[L]<=p and L<R:
L+=1
swap(b,c)
swap(L,pL)
paixu(0,len(a)-1)
接下来我们通过递归来实现排序
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
a = [12,45,65,43,54,10,76]
def paixu(pL,pR):
p = a[pL]
L = pL
R = pR
while L<R:
while a[R]>=p and L<R:
R-=1
while a[L]<=p and L<R:
L+=1
swap(b,c)
swap(L,pL)
paixu(pL,L-1)
paixu(L+1,pR)
paixu(0,len(a)-1)
因为我们这种使用方法是递归,我们需要注意以下条件:
某种情况下使递归停止
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
a = [12,45,65,43,54,10,76]
def paixu(pL,pR):
if pL==pR:
return 0
p = a[pL]
L = pL
R = pR
while L<R:
while a[R]>=p and L<R:
R-=1
while a[L]<=p and L<R:
L+=1
swap(b,c)
swap(L,pL)
paixu(pL,L-1)
paixu(L+1,pR)
paixu(0,len(a)-1)
但是这还是存在有问题,停止条件需要添加L<R以防止出现将R走过的数据重新走遍
所以
#快速排序
a = [12,45,65,43,54,10,76,5]
def swap(b,c):
temp = a[b]
a[b] = a[c]
a[c] = temp
def paixu(pL,pR):
if pL==pR or pL>pR:#递归注意停止条件,当两个指针碰一起就停止因为只有一个数字
return 0
p = a[pL]
L = pL
R = pR
while L<R: #L==R 代码停止 L>R
#比较右指针对应数据大小,将第一个比中心轴数字小的对应下标打印
while a[R]>=p and L<R:
R = R - 1
#比较左指针数据大小,将第一个比中心轴数字大的对应下标打印
while a[L]<=p and L<R:
L = L + 1
swap(L,R)
#第一轮左右指针移动后,L指向索引为1的数字,R指向索引为5数字
#接下来R继续移动
swap(pL,L) #完成一轮排序
print(a,pL,pR,L)
paixu(L+1,pR)#分析左右分支
paixu(pL,L-1)
paixu(0,len(a)-1)
print(a)