快速排序清晰解法,有无重复元素
1. 快速排序(不含重复元素值)
先选start值为基准值ref,从start+1到end区间,双指针i、j交换位置(目的是把比ref小的放左边,比ref大的放右边,其实就是为了找到基准值应该在的位置),然后当i > j 的时候说明全部遍历完了,此时,j所在的位置就是基准值的位置。
找到基准值后,将基准值前后的数组递归调用函数本身,就可以排好序了。
def QuickSort(arr, start, end):
if start >= end:
return arr
ref = arr[start]
i = start + 1
j = end
while i <= j:
if arr[i] < ref:
i += 1
continue
if arr[j] > ref:
j -= 1
continue
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
arr[start] = arr[j]
arr[j] = ref
QuickSort(arr, start, j - 1)
QuickSort(arr, j + 1, end)
return arr
2. 快速排序(含相同元素值)
上面的方法已经不能满足,因为如果有重复元素值会陷入死循环。
采用三向切分,将数组分为三部分:小于当前切分元素(即基准值)的部分,等于当前切分元素的部分,大于当前切分元素的部分。
由于基准可能存在重复值,每次遍历多了一个指针,基准所在位置lo。所以三个指针分别为:lo(基准当前位置)、lt(基准后一个值的位置)、gt(数组最后一个值)。
遍历终止条件和一一样:即lt>gt时退出循环。目的也一样:将小于基准值的放前面,大于基准值的放后面,等于基准值的在一起。
遍历有三种情况:
① 基准值lo小于后一个值lt:那么直接将lt所在位置的值与数组最后一个值gt交换,然后gt-1;
② 基准值lo大于基准后一个值lt:lo和lt所在位置的值交换,并且lo+1,lt+1;
③ 基准值lo和后一个值lt相等:说明基准值有重复。lt++
退出循环后,进行递归。
基准前:start, lo-1
基准后:lt, end
def QuickSort2(arr, start, end):
if start >= end:
return arr
lo = start # 基准
lt = start + 1 # 基准后一个值
gt = end # 数组最后一个值
while lt <= gt:
if arr[lo] < arr[lt]: # 基准小于后一个值,直接将后一个值扔到数组最后,并且gt-1
temp = arr[lt]
arr[lt] = arr[gt]
arr[gt] = temp
gt -= 1
elif arr[lo] > arr[lt]: # 基准大于后一个值,交换这两个值,然后lo、lt都加1
temp = arr[lo]
arr[lo] = arr[lt]
arr[lt] = temp
lo += 1
lt += 1
elif arr[lo] == arr[lt]: # 基准后一个值加一
lt += 1
QuickSort2(arr, start, lo - 1)
QuickSort2(arr, lt, end)
return arr
以上就是快速排序的全部内容了。
码字不易,点个赞吧!希望自己转码顺利!