快速排序法

  1. 什么是快速排序?
    快速排序是一个既高效又不浪费空间的一种排序算法。首先我们需要设定中心轴,将大于中心轴的数据放在中心轴的左边,小于中心轴的数据放在中心轴的右边。

  2. 快速排序的排序流程
    所以,我们需要设定中心轴以及左右两边两个指针。这里设定为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)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值