快速排序学习

最基础的快速排序


public class 快速排序test {
    public static void main(String[] args) {
        int a[]=new int[]{1,3,6,9,14,0,89,4,5};
        if(a != null && a.length>=2){
            quickSort(a,0,a.length-1);
        }
        System.out.println(Arrays.toString(a));
    }
   private  static void quickSort(int arr[],int start, int end){
        if(start>=end){
            return;
        }
        int left = start;
        int right = end;
        int temp = arr[right];//选用最右边节点作为参考点
        while(left<right){
            //从两边开始遍历   因为选取的是右边节点,所以先从左边开始遍历
            while(arr[left]<temp&&left<right){
                left++;
            }
            while(arr[right]>=temp&&left<right){
                right--;
            }
                swap(arr, left, right);
        }
        //交换参考点和right 把参考点换到中间
        swap(arr,right,end);
        quickSort(arr, start, right-1 );
        quickSort(arr, right+1,end);

    }
    private static void swap(int arr[], int left, int right){
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
    }

}

可以从很多方面做优化

比如 从参考点选取方面 每次随机选取一个做参考点

再比如这样每次循环只能确定一个数的位置 就算中间的数字重复 也是只能确定一个

比如 5 , 1 , 5,  2, 5  , 6,  7 , 5

只能确定一个5 的位置 其余的5还会参与下次循环。

修改调换位置的算法 使得一次能确定所有的5

参考荷兰国旗问题

public class 快速排序test2 {
    public static void main(String[] args) {
        int a[]=new int[]{1,3,6,9,14,0,89,4,5};
        if(a != null && a.length>=2){
            quickSort(a,0,a.length-1);
        }
        System.out.println(Arrays.toString(a));
    }
   private  static void quickSort(int arr[],int start, int end){
        if(start>=end){
            return;
        }
        swap(arr, start+new Random().nextInt(end-start+1),end);
        int[] p =partition(arr, start, end);   //p[0]  代表中间相等的参考值数组左下标 p[1]代表中间相等的参考值数组右下标
        quickSort(arr, start, p[0]-1 );
        quickSort(arr, p[1]+1,end);

    }
    private  static int[] partition(int arr[],int l, int r){
        int less = l-1;    //左边界
        int more = r;      //右边界
        while(l < more){
            if(arr[l] < arr[r]){   //如果小于参考值  和左边界下一位交换 左边界扩大一位 l向右移动
                swap(arr, ++less, l++);
            }else if(arr[l] > arr[r]){ //如果大于参考值   和右边界前一位交换 右边界向左扩大一位   由于从右边界换来的数大小不确定 所以l再做判断
                swap(arr, --more, l);
            }else{                 //如果等于参考值  l向右边移动
                l++;
            }
        }
        swap(arr, more, r);      //交换参考值和右边界的值
        return new int[]{less+1,more};
    }
    private static void swap(int arr[], int left, int right){
        int temp = arr[left];
        arr[left] = arr[right];
        arr[right] = temp;
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值