快速排序(java)

快排又被称为分割交换排序法,好像总会在面试或者笔试中做为考察点来考察,快排也是目前常见的一些排序算法中很不错的排序方法了(均衡考量平均时间运行较快,所以我想说最佳排序来着,不过怕被打脸)。

**快速排序关键步骤**(从左往右由小到大):
 1.  取一个键值K做为参照
 2.  从左到右依次查找,找到一个Ki使得Ki>K
 3.  从右到左依次查找,找到一个Kj使得Kj<K
 4.i<j则Ki与Kj交换、并继续步骤2的执行。
 5.i>=j,则将k与Kj交换,并且以J为基准点将其分为左右俩部分,并按上述方式进行递归求解排序,直至完成。

例子:按照快排的方式将下列元素排序

        28   6  40  2  63  9  58  16  47  20
第一次  K=28          i                    j
因为i<j,故交换Ki与Kj,然后继续比较:

        28   6  20  2  63  9  58  16  47  40
                       i           j
因为这时i<j故交换位置继续比较:

        28   6  20  2  16  9  58  63  47  40

因为i>=j,故交换K与Kj,并以j为基准点分割为左右俩半:

       [ 9   6  20  2  16] 28 [58 63  47  40]

这样一轮下来就达到这样的效果:以28(最开始我们的K)为基准,左边都是小于28的,右边都是大于28的。忽略俩边排序的话,28已经到达它应该到的位置上了, 所以 ,依次类推的递归,对左右俩边的部分继续这样执行,这样执行完毕就会达到排序的效果。

给出代码实现:

public class QuickSort {

    private int[] array = { 28, 6, 40, 2, 63, 9, 58, 16, 47, 20 };

    public static void main(String[] args) {
        QuickSort quickSort = new QuickSort();
        System.out.print("排序前:");
        quickSort.print(quickSort.array);
        quickSort.quick(quickSort.array, 0, quickSort.array.length-1);
        System.out.print("排序结果:");
        quickSort.print(quickSort.array);
    }

    private void print(int[] array) {
        for(int i=0;i<array.length;i++) {
            System.out.print(array[i]+ " ");
        }
        System.out.println();
    }

    private void quick(int[] arr, int left, int right) {
        int left_ids;
        int right_ids;
                                //第一个键值为arr[left]
        if(left < right) {
            left_ids = left + 1;
            right_ids = right;

            while(true) {
                System.out.print("处理过程:");
                for(int tmp : arr) {
                    System.out.print("[" + tmp + "]");
                }
                System.out.println();

                for(int i=left+1; i<=right; i++) {
                    if(arr[i] >= arr[left]){
                        left_ids = i;
                        break;
                    }
                    left_ids++;
                }

                for (int j=right; j>=left+1;j--) {
                    if(arr[j] <= arr[left]) {
                        right_ids = j;
                        break;
                    }
                    right_ids--;
                }

                if(left_ids<right_ids) {
                    int tmp = arr[left_ids];
                    arr[left_ids] = arr[right_ids];
                    arr[right_ids] = tmp;
                } else {
                    break;
                }
            }

            if(left_ids >= right_ids) {
                int tmp = arr[left];
                arr[left] = arr[right_ids];
                arr[right_ids] = tmp;
                quick(arr, left, right_ids-1);
                quick(arr, right_ids+1, right);
            }
        }
    }
}

运行结果截图:
这里写图片描述

还有一种常见的写法如下:

  public static int partition(int []array,int lo,int hi){
        //固定的切分方式
        int key=array[lo];
        while(lo<hi){
            while(array[hi]>=key&&hi>lo){//从后半部分向前扫描
                hi--;
            }
            array[lo]=array[hi];
            while(array[lo]<=key&&hi>lo){从前半部分向后扫描
                lo++;
            }
            array[hi]=array[lo];
        }
        array[hi]=key;
        return hi;
    }

    public static void sort(int[] array,int lo ,int hi){
        if(lo>=hi){
            return ;
        }
        int index=partition(array,lo,hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi); 
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值