排序算法之快速排序和归并排序-Java实现

快速排序

快速排序是对冒泡排序的进一步改进。排序思想主要是每次找一个基准数,小于基准数的放前面,大于基准数的放后面,再依次对基准数左边和右边的数组进行相同的操作,递归实现
时间复杂度:最好的情况是O(nlogn),最差的情况是O(n^2)

public static void main(String[] args) {
        int[] arr = {1, 232, 4, 3, 5, 7, 84, 6};
        printf(arr);

        sort(arr, 0, arr.length - 1);
        System.out.println();
        printf(arr);
    }

    public static void sort(int[] arr, int left, int right) {
        //最后一个数不用拆分找基准数了
        if (left > right) return;

        //找基准数的下标
        int basic = parition(arr, left, right);
        //对基准数左边的进行排序
        sort(arr, left, basic - 1);
        //对基准数右边的进行排序
        sort(arr, basic + 1, right);
    }

    public static int parition(int[] arr, int left, int right) {
        //默认最后一个数为基准数
        //两个指针i,j,j往右边移直到j>=right停止
        //如果j位置的数比基准数小,那么就交换i和j位置的数,i++
        int pos = arr[right];
        int i = left;
        for (int j = left; j < right; j++) {
            if (arr[j] < pos) {
                //交换
                swap(arr, i, j);
                i++;
            }
        }
        //j=right的时候,将i和基准数交换,结束此次排序,返回i,为下一个基准数的位置
        swap(arr, i, right);
        return i;
    }

    //在数组arr中将i和j下标的值进行交换
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void printf(int[] num) {
        for (int a : num) {
            System.out.print(a + " ");
        }
    }

归并排序

归并排序的思想是分而治之,将要排序的数组进行平分,平分到最小粒度的时候,对左右两边的数组进行比较和归并
时间复杂度为:O(nlogn)

public static void main(String[] args) {
        int[] arr = {12, 56, 5, 6, 3, 6, 1, 4, 7, 8, 2};
        printf(arr);
        divide(arr, 0, arr.length - 1);
        System.out.println();
        printf(arr);
    }

    public static void divide(int[] arr, int left, int right) {
        if (left < right) {
            //进行划分
            int mid = (left + right) / 2;
            divide(arr, left, mid);
            divide(arr, mid + 1, right);
//            这是一个最小粒度,进行比较,合并
            merge(arr, left, right, mid);
        }
    }

    public static void merge(int[] arr, int left, int right, int mid) {
        int[] temp = new int[right - left + 1];
        int i = left;
        int j = mid + 1;
        int tempIndex = 0;

        while (i <= mid && j <= right) {
            //两边数组都有值,比较大小
            if (arr[i] < arr[j]) {
                temp[tempIndex++] = arr[i++];
            } else {
                temp[tempIndex++] = arr[j++];
            }
        }
        //右边的已经没有数了,左边的放进临时数组就行
        while (i <= mid) {
            temp[tempIndex++] = arr[i++];
        }
        //左边的已经没有数了,右边的放进临时数组就行
        while (j <= right) {
            temp[tempIndex++] = arr[j++];
        }

        //将原数组的值替换为临时数组的值
        for (int k = 0; k < temp.length; k++) {
            arr[left + k] = temp[k];
        }

    }

    public static void printf(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值