快速排序-java

快速排序

原理

快递排序其实是一个递归的过程。

快速排序中任意指定一个数为中轴值,将小于该数的都放到它的左边,大于该数的都放到它的右边。然后对它的左子序列和右子序列继续做快速排序。

过程

  • 规定序列左边的第一个数为pivot,两个指针left和right分别指向序列的左边和右边;
  • 因为后面递归还需要用到left和right,所以使用l和r保存left和right的值,使用l和r进行移动定位;
  • 右边开始(因为我将最左边的数作为pivot,所以从右边开始,如果将最右边的数作为pivot,则从最左边开始),寻找比基准值小的数,就停住;
  • 接着从左边开始,寻找比基准值大的数,停住;
  • 交换a[l]和a[r];
  • 依次反复,直到l和r相遇,将a[l/r]放到pivot所在的位置a[left],pivot放到a[l/r],一次快速排序就结束。
  • 此时pivot左边的数都比pivot小,右边都比pivot大。
  • 递归地对左子序列和右子序列做上面的过程。

代码实现

/**
     * 快速排序交换法
     * 规定序列左边的第一个数为pivot,两个指针left和right分别指向序列的左边和右边
     * 因为后面递归还需要用到left和right,所以使用l和r保存left和right的值,使用l和r进行移动
     * r是从右边开始找比pivot小的数,l是从左边开始找比pivot大的数
     * 从右边开始找,找到比pivot小的就停住,然后从左边开始找比pivot大的停住,交换两个指针指向的数。(前提是l<r)
     * 如果在寻找的过程中,l=r,就将pivot和a[l](或a[r])交换
     *
     * @param a
     * @param left
     * @param right
     */
public static void quickSort(int[] a, int left, int right) {
    if (left >= right) return;
    int pivot = 0;
    int l = left;
    int r = right;
    int temp;
    while (true) {
        pivot = a[left];
        while (a[r] >= pivot && l < r) r--;
        while (a[l] <= pivot && l < r) l++;
        if (l == r) break;
        temp = a[r];
        a[r] = a[l];
        a[l] = temp;
    }
    if (l != left) {
        a[left] = a[l];
        a[l] = pivot;
    }
    //对左子序列进行快速排序
    quickSort(a, left, l - 1);
    //对右子序列进行快速排序
    quickSort(a, l + 1, right);
}
/**
 * 快速排序移位法
 * 令两个指针left和right分别指向数组的左边和右边,将数组中的第一个值看做基准值pivot,从右边开始,寻找比基准值小的数,放到a[left]的位置;
 * 然后从左边开始,寻找比基准值大的数,放到a[right]的位置;依次反复,直到left和right相遇,那么第一次快速排序就结束。
 *
 * @param a
 */
public static void quickSort1(int[] a, int left, int right) {
    if (left >= right) return;
    int pivot = a[left];
    int l = left;
    int r = right;
    while (true) {
        while (a[r] >= pivot && l < r) {
            r--;
        }
        a[l] = a[r];
        while (a[l] <= pivot && l < r) {
            l++;
        }
        a[r] = a[l];
        if (l == r) break;
    }
    a[l] = pivot;
    quickSort1(a, left, l - 1);
    quickSort1(a, l + 1, right);
}

以上两段代码都可实现快速排序,经过测试排序1000万数据平均用时1.048s。移位法和交换法的区别不是很大,通过debug可以看到整个排序的详细过程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值