排序算法(二):快速排序

思想:每次循环确定一个元素的最终位置,每次循环设置当前数组的第一个元素为基准值,这一趟循环中,每个元素和这个基准值进行比较。

时间复杂度:最好(n*log(n)),最坏(n*2),平均(n*log(n))

Python版本:

# 快速排序
class Solution:
    def QuickSort(self, Arr):
        n = len(Arr)
        self.Sort_(Arr, 0, n - 1)
        return Arr

    def Sort_(self, arr, left, right):
        if left>=right:return  #终止条件
        i = left
        j = right
        pivot = arr[left] # 注意这里是left,不能写0
        while i < j:
            while i < j and arr[j] >= pivot:
                j -= 1
            if i < j:
                arr[i] = arr[j]
            while i < j and arr[i] <= pivot:
                i += 1
            if i < j:
                arr[j] = arr[i]
            arr[i] = pivot
        self.Sort_(arr, left, i - 1)
        self.Sort_(arr, i + 1, right)


print(Solution().QuickSort([3, 5, 1, 2, 5, 7, 9, 0]))

Java版本:

public class QuickSort {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 5, 1, 2, 5, 7, 9, 0};
        FastSort(arr,0,arr.length-1);
        System.out.println(java.util.Arrays.toString(arr));
    }

    public static void FastSort(int[] arr,int left,int right){
        if (left>=right){ //终止条件始终,首先写
            return;
        }
        int pivot = arr[left];
        int i = left;
        int j = right;
        while(i<j){
            while(i<j && arr[j]>=pivot){//边界判断
                j--;
            }
            if(i<j){
                arr[i] = arr[j];//值的交换
            }
            while (i<j && arr[i]<=pivot){//边界判断
                i++;
            }
            if (i<j){
                arr[j] = arr[i];//值的交换
            }
            arr[i] = pivot;
        }
        FastSort(arr,left,i-1);
        FastSort(arr,i+1,right);
    }
}

问题及优化:

当每次都能平均划分序列时,此时时间复杂度为最优;而当每次划分都是划分成一个元素和其他序列时,此时快速排序退化为冒泡排序;

优化:每次设置基准数时,采用“三者取中”的原则:在没趟划分前比较分段中第一个、最后一个和位置居中的三个记录的关键码,取这3个关键码对应的值中数值处于中间大小的值,将这个居中值的记录与首记录交换。(注意,可以减少最坏情况出现的概率,但是无法消除最坏情况)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值