快速排序及优化

快速排序比起冒泡排序一般要快上许多,他的思想是将要排序的数据不断切割,分而治之。

下面是基本的快速排序写法:

public static void quickSort1(int[] arr, int i, int j){
        int start = i;
        int end = j;
        int temp = arr[i];
        while (i < j){
            while (i < j && temp < arr[j]){
                --j;
            }
            while (i < j && arr[i] < temp){
                ++i;
            }
            if (i < j && arr[i] == arr[j]){
                ++i;
            } else {
                int temp1 = arr[i];
                arr[i] = arr[j];
                arr[j] = temp1;
            }
        }
        if (start < i){
            quickSort1(arr, start, i - 1);
        }
        if (j < end){
            quickSort1(arr, j + 1, end);
        }
    }

它将最左边的数作为基准,分别将大于它和小于等于它的数放在两边切割排序。
它的时间复杂度是在n*logn和n平方之间,当数据已排序,每次指挥切割一个数据,时间复杂度为n平方,所以我们可以用随机数来设置基准

public static void quickSort2(int[] arr, int i, int j){
        int start = i;
        int end = j;
        int random = new Random().nextInt(j - i + 1) + i;
        int temp = arr[random];
        while (i < j){
                while (i < j && temp < arr[j]){
                    --j;
                }
                while (i < j && arr[i] < temp){
                    ++i;
                }
                if (i < j && arr[i] == arr[j]){
                    ++i;
                } else {
                    int temp1 = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp1;
                }
            }
            if (start < i){
                quickSort2(arr, start, i - 1);
            }
            if (j < end){
                quickSort2(arr, j + 1, end);
            }
        }

但是随机数并不能有效解决这个问题,于是就来了三数(最左、中间、最右)取中设置基准,让最左边的数为三个数的中间值

public static void quickSort3(int[] arr, int i, int j){
        int start = i;
        int end = j;
        int mid = (i + j) >> 1;
        if (arr[start] < arr[mid]) {
            swap(arr, start, mid);
        }
        if (arr[end] < arr[mid]) {
            swap(arr, end, mid);
        }
        if (arr[start] > arr[end]) {
            swap(arr, start, end);
        }
        int temp = arr[start];
        while (i < j){
            while (i < j && temp < arr[j]){
                --j;
            }
            while (i < j && arr[i] < temp){
                ++i;
            }
            if (i < j && arr[i] == arr[j]){
                ++i;
            } else {
                int temp1 = arr[i];
                arr[i] = arr[j];
                arr[j] = temp1;
            }
        }
        if (start < i){
            quickSort3(arr, start, i - 1);
        }
        if (j < end){
            quickSort3(arr, j + 1, end);
        }
    }

前面都是每次两两划分数据,将等于基准的数归到了小于的数据一起划分,其实这就是多余的部分,我们可以将等于基准的数据放在一起,减少划分次数,于是三路划分的快排就来了

public static void quickSort4(int[] arr, int i, int j){
        int start = i;
        int end = j;
        int mid = (i + j) >> 1;
        if (arr[start] < arr[mid]) {
            swap(arr, start, mid);
        }
        if (arr[end] < arr[mid]) {
            swap(arr, end, mid);
        }
        if (arr[start] > arr[end]) {
            swap(arr, start, end);
        }
        int temp = arr[start];
        while (i < j){
            while (i < j && temp < arr[j]){
                --j;
            }
            while (i < j && arr[i] < temp){
                ++i;
            }
            if (i < j && arr[i] == arr[j]){
                ++i;
            } else {
                int temp1 = arr[i];
                arr[i] = arr[j];
                arr[j] = temp1;
            }
        }
        int count1 = 1;
        int count2 = 1;
        ok:for (int k = start; k < i - count1; k++) {
            if (arr[k] == arr[i]){
                while (arr[i - count1] == arr[i]){
                    if ((i - count1) == k){
                        break ok;
                    }
                    ++count1;
                }
                swap(arr, k, i - count1++);
            }
        }
        ok:for (int k = end; k > j + count2; k--) {
            if (arr[k] == arr[j]){
                while (arr[j - count2] == arr[j]){
                    if ((j + count2) == k){
                        break ok;
                    }
                    ++count2;
                }
                swap(arr, k, j + count2++);
            }
        }
        if (start < i){
            quickSort4(arr, start, i - count1);
        }
        if (j < end){
            quickSort4(arr, j + count2, end);
        }
    }

上面是作为一个小菜比的总结,如有不当之处,请大家指出,多多包涵

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值