快速排序

思想

快速排序是基于分治策略的。对一个子数组A[p…r]快速排序的分治过程的三个步骤为:

分解:

数组A[p…r]被划分成两个(可能空)子数组A[p…q-1]和A[q+1…r],使得A[p…q-1]中的每个元素都小于等于A[q],且小于等于A[q+1…r]中的元素。下标q也在这个划分过程中进行计算。

解决:

通过递归调用快速排序,对子数组A[p…q-1]和A[q+1…r]排序。

合并:

因为两个子数组就是原地排序的,将它们的合并不需要操作:整个数组A[p…r]已排序。
伪代码

这里写图片描述

算法的关键是求q的partition过程,它实现子数组A[p,..,r]的原地址重排

伪代码
这里写图片描述

算法选取数组的右边界A[r]作为分裂元素

动画

这里写图片描述
动画来源

讲解

这里写图片描述

可以看出p-i部分的数都小于等于x,i+1–j部分的数都大于j

在(b)情况:i++,交换后A[i]的值小于等于x,而原始A[i]的值本身就是大于x的交换到j的位置当然也是大于x的

最后当j==r时候,i++后也需要进行交换,虽然A[i]大于x,当时A[r]的值是等于x。快排是:左边的是小于等于x,右边的大于x

partition函数

public int partition(int [] A,int low ,int high){
        int x = A[high];
        int i = low - 1;
        for( int j = low;j<= high - 1;j++){
            if( A[j] <= x){
                i = i + 1;
                swap(A,i,j);
            }
        }
        i = i + 1;
        swap(A,i,high);
        return i;
    }

    public void swap(int[] array,int i,int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

求划分id的partition函数的另外一种写法

核心思想:找到左侧大于x的数a,找到右侧小于x的数b,a、b交换,继续寻找,两个指针相遇时候结束,这样结束后左侧的数小于想,右侧的数大于x,两侧的数递归上面方法

public int Paratition(int[] A,int left ,int right){
        if(left> right)
            return -1;
        int i = left;
        int j = right;
        int mid = A[left];
        if(i<j){
            while(i<j){
                while(i<j && mid< A[j])
                    j--;
                if(i<j){
                    A[i] = A[j];
                    i++;
                }
                while(i<j && A[i]< mid)
                    i++;
                if(i<j){
                    A[j] = A[i];
                    j--;
                }
            }
            A[i] = mid;
        }
        return i;

    }

快排函数

public void quickSort(int[] A,int left,int right){
        if(left>right)
            return;
        int id = partition(A,left,right);
        quickSort(A,left,id-1);
        quickSort(A,id+1,right);

    }

复杂度分析

(1)时间复杂度
最好情况: O(nlog2n)
最坏情况:原始数组有序 O(n2) ,当原始数组接近有序的时候算法效力低
平均时间复杂度 O(nlog2n)
(2)空间复杂度
快排是递归进行的,递归需要栈的辅助,空间复杂度 O(log2n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值