十大排序(一)

今天我们来说说十大排序
十大排序可分为两类:一类是比较类,另一类是非比较类;而比较类可分为交换类、选择类、插入类、归并类;非比较类可分为桶排。
下面我们来看看比较类中的交换类:冒泡排序和快速排序

在这里插入图片描述
冒泡排序
比较相邻的元素。如果第一个比第二个大,就交换它们两个;
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
针对所有的元素重复以上的步骤,除了最后一个;

 public int[] bubbleSort(int[] A, int n) {
        //冒泡排序:从后往前(从下往上)就像冒泡一样
        //用flag作为标记,标记数组是否已经排序完成
        boolean flag = true;
        //固定左边的数字
        for (int i = 0; i < n - 1 & flag; i++) {
            flag = false;
            //从后面(下面)往前(上)遍历
            for (int j = n - 2; j >= i; j--) {

                if (A[j] > A[j + 1]) {
                    swap(A, j, j + 1);
                    flag = true;
                }
            }
        }

        return A;

    }

快速排序
从数列中挑出一个元素,称为 “基准”(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

 public int[] quickSort(int[] A, int n) {
        //快速排序
        qSort(A,0,n-1);
        return A;
    }

    /**
     *
     * @param A
     * @param left
     * @param right
     */
    public void qSort(int[] A,int left,int right){
        //枢轴
        int pivot;
        if(left<right){

            pivot = partition(A,left,right);
            qSort(A,left,pivot-1);
            qSort(A,pivot+1,right);

        }

    }

    /**
     *  优化选取一个枢轴,想尽办法把它放到一个位置,使它左边的值都比它小,右边的值都比它大
     * @param A
     * @param left
     * @param right
     * @return
     */
    public int partition(int[] A,int left,int right){

        //优化选取枢轴,采用三数取中的方法
        int pivotKey = median3(A,left,right);
        //从表的俩边交替向中间扫描
        //枢轴用pivotKey给备份了
        while(left<right){
            while(left<right&&A[right]>=pivotKey){
                right--;
            }
            //用替换方式,因为枢轴给备份了,多出一个存储空间
            A[left]=A[right];
            while(left<right&&A[left]<=pivotKey){
                left++;
            }
            A[right]=A[left];

        }

        //把枢轴放到它真正的地方
        A[left]=pivotKey;
        return left;
    }

    /**
     * 三数取中
     * @param A
     * @param left
     * @param right
     * @return
     */
    public int median3(int[] A,int left,int right){
        int mid=(right-left)/2;
        if(A[left]>A[right]){
            swap(A,left,right);
        }
        if(A[mid]>A[left]){
            swap(A,mid,left);
        }
        if(A[mid]>A[right]){
            swap(A,mid,right);
        }

        return A[left];
    }

 /**
     * 数组是按引用传递,在函数中改变数组起作用
     * @param A
     * @param i
     * @param j
     */
    private void swap(int[] A, int i, int j) {
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }

这些事本人网上学习真理的一些拙见,仅供参考

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值