快速排序算法(JAVA)

快排

  • 设立基准值,以基准值为中心,根据分治思路把大于基准值放一边,小于基准值放另一边。
  • 递归上一步的操作。

基准值获取想法

  • 1.从最左或最右或中间或随机或三取中。
  • 2.基准值的获取直接影响了时间算法的复杂度,理想情况是0(nlogn),最坏情况是n^2。
  • 3.所以快排算法是不稳定的。

第一种:取最左边值为基准值

/    左边为基准
    public static int[] quickSortLeft(int[] num, int leftPos, int rightPos) {
        if (rightPos < leftPos)
            return num;
        else {
//            step1:选择基准数
            int initLeftPos = leftPos;
            int initRightPos = rightPos;
            int pivot = num[leftPos];

            while (rightPos > leftPos) {
//             step2:从右边开始寻找第一个小于基准数的index
                while (num[rightPos] >= pivot && rightPos > leftPos) {
                    rightPos--;
                }
//             step3:从左边开始寻找第一个大于基准数的index
                while (num[leftPos] <= pivot && rightPos > leftPos) {
                    leftPos++;
                }
//                如果符合条件则交换,就是把小于基准数的换到基准数左边
                if (rightPos > leftPos)
                    swap(num, leftPos, rightPos);
            }
//            step4:把基准数归位
            swap(num, leftPos, initLeftPos);
//            step5:基准数左边继续做步骤step1~step4
            quickSortLeft(num, initLeftPos, leftPos - 1);
//            step6:基准数右边继续做步骤step1~step4
            quickSortLeft(num, rightPos + 1, initRightPos);
            return num;
        }
    }

第二种:取最右边值为基准值

要注意的是,与取左边为基准不一样的是,得先从右边开始查找第一个比基准数小的index,(取左边为基准时,先从左边查找比基准数大的index)

/右边为基准
    public static int[] quickSortRight(int[] num, int leftPos, int rightPos) {
        if (rightPos < leftPos)
            return num;
        else {
            int initLeftPos = leftPos;
            int initRightPos = rightPos;
            int pivot = num[rightPos];

            while (rightPos > leftPos) {
                while (num[leftPos] <= pivot && rightPos > leftPos) {
                    leftPos++;
                }
                while (num[rightPos] >= pivot && rightPos > leftPos) {
                    rightPos--;
                }
                if (rightPos > leftPos)
                    swap(num, leftPos, rightPos);
            }
            swap(num, rightPos, initRightPos);
            quickSortRight(num, initLeftPos, leftPos - 1);
            quickSortRight(num, rightPos + 1, initRightPos);
            return num;
        }
    }

第三种:取中间值为基准值

第四种:取随机index对应的值为基准值

可以是只取一次随机,然后直接使用取左边/右边为基准算的方法,这里是每次递归都取一次随机基准数

 //    随机基准
    public static int[] quickSortRand(int[] num, int leftPos, int rightPos) {
        if (rightPos <= leftPos)
            return num;
        else {
            int random = new Random().nextInt(rightPos+1) % (rightPos-leftPos) + leftPos;
//			  把基准数换到左边
            swap(num, leftPos, random);
//            step1:选择基准数
            int initLeftPos = leftPos;
            int initRightPos = rightPos;
            int pivot = num[leftPos];

            while (rightPos > leftPos) {
//             step2:从右边开始寻找第一个小于基准数的index
                while (num[rightPos] >= pivot && rightPos > leftPos) {
                    rightPos--;
                }
//             step3:从左边开始寻找第一个大于基准数的index
                while (num[leftPos] <= pivot && rightPos > leftPos) {
                    leftPos++;
                }
//                如果符合条件则交换,就是把小于基准数的换到基准数左边
                if (rightPos > leftPos)
                    swap(num, leftPos, rightPos);
            }
//            step4:把基准数归位
            swap(num, leftPos, initLeftPos);
//            step5:基准数左边继续做步骤step1~step4
            quickSortRand(num, initLeftPos, leftPos - 1);
//            step6:基准数右边继续做步骤step1~step4
            quickSortRand(num, rightPos + 1, initRightPos);
            return num;
        }
    }

第五种:三取中

基本思想:

  1. 取第一个数,最后一个数,第(N/2)个数即中间数,三个数中数值中间的那个数作为基准值。举个例子,对于int a[] = { 2,5,4,9,3,6,8,7,1,0};,‘2’、‘3’、‘0’,分别是第一个数,第(N/2)个是数以及最后一个数,三个数中3最大,0最小,2在中间,所以取2为基准值。
  2. 取第一个数,最后一个数,随机的一个数,三个数中数值中间的那个数作为基准值。

swap方法

//swap方法:将数组中leftPos和rightPos上的两个数值进行交换
    public static void swap(int[] num, int leftPos, int rightPos) {
        int temp = num[leftPos];
        num[leftPos] = num[rightPos];
        num[rightPos] = temp;
    }

测试

 public static void main(String[] args) {
        int[] num = new int[]{9,1,5,3,10,8,2,7,6,4,4,5};
        for (int a : quickSortRand(num, 0, num.length - 1)) {
            System.out.print(a + " ");
        }
    }

测试结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值