python实现快速排序及相关问题

1.概念引入

(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。 [2]
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

2 编写代码

def QuickSort(arr):
    if len(arr)<2:#函数结束标志
        return
    mid=arr[0]#假设分界值为第0个元素
    start=1
    end=len(arr)-1
    while start<end:
        while arr[start]<mid and start<end:
            start+=1#搜素比分界值大的元素索引
        while arr[end]>mid and end>0:
            end-=1#搜索比分界值小的元素索引
        if start<end:
            arr[start],arr[end]=arr[end],arr[start]#交换
    arr[0],arr[end]=arr[end],arr[0]#将分界值放在序列的相应位置
    QuickSort(arr[0:end])
    QuickSort(arr[end+1:len(arr)])
arr=[5,2,33,23,14,12]
QuickSort(arr)
print(arr)

结果如下,可以发现序列中只有2和5的位置发生了变换而其他元素没有发生改变,经分析代码可知QuickSort(arr[0:end])和QuickSort(arr[end+1:len(arr)])这两
句代码没有得到相应的结果,而从逻辑上分析这样的代码并没有错。
在这里插入图片描述
后来我经过自己实验发现了相应的问题,原来是列表切片的问题,先观察如下代码

arr=[5,2,33,23,14,12]
arr0=arr[0:3]
arr0[1]=12
print(arr)

这里代码结果如下
在这里插入图片描述
发现没,虽然我们改变了切片中的值,但是在原始的序列中的值并没有发生改变
我们可以从这里得知切片只是相应的序列的一个副本,改变切片的值并不会影响原始序列。
所以将代码改为如下之后便可以

def QuickSort(arr,low,high):
    if high-low<2:
        return
    mid=arr[low]
    i=low+1
    j=high
    while i<j:
        while arr[i]<mid and i<high:
            i+=1
        while arr[j]>mid and j>low:
            j-=1
        if i<j:
            arr[i],arr[j]=arr[j],arr[i]
    arr[low],arr[j]=arr[j],arr[low]
    QuickSort(arr,0,j)
    QuickSort(arr,j+1,high)
arr=[5,2,33,23,14,12]
QuickSort(arr,0,5)
print(arr)

最后附上官方的python代码

def quick_sort(data):    
    """快速排序"""    
    if len(data) >= 2:  # 递归入口及出口        
        mid = data[len(data)//2]  # 选取基准值,也可以选取第一个或最后一个元素        
        left, right = [], []  # 定义基准值左右两侧的列表        
        data.remove(mid)  # 从原始数组中移除基准值        
        for num in data:            
            if num >= mid:                
                right.append(num)            
            else:                
                left.append(num)        
        return quick_sort(left) + [mid] + quick_sort(right)    
    else:        
        return data

以上若有不恰当之处,敬请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值