整理排序算法 java

这里写图片描述
这是之前不知道什么时候从网上截图下来的,找不到出处了,超级棒的笔记

冒泡排序

//冒泡
    public void bubleSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {//循环n-1次,每循环完一次,冒泡得一个最大值
            for (int j = 0; j < nums.length - i - 1; j++) {
                if (nums[j] > nums[j + 1]) {
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }

            }
        }
    }

冒泡的思维是很简单的,第i次比较,若nums[j]>nums[j+1],交换位置,总共有N-1趟排序,每趟排序次数是N-i次
时间复杂度:最好情况下是已排好序的情况,时间复杂度为O(n),最坏情况是O(n^2),平均时间复杂度为O(n^2)
空间复杂度:O(1)


归并排序

归并排序的基本思想是:将待排序元素分成大小大致相同的2个子集合,分别2个集合进行排序,最终将排序好的子集合合并成为所要求的有序的集合。总时间为:分解时间+排序时间+合并时间

合并算法可递归的描述如下

//合并排序
    public void mergeSort(Comparable a[], int left, int right) {
        Comparable b[] = new Comparable[a.length];
        if (left < right) {
            int i = (left + right) / 2;
            mergeSort(a, left, i);
            mergeSort(a, i + 1, right);
            merge(a, b, left, i, right);//合并到数组b
            copy(a, b, left, right);//复制回数组a
        }
    }

    //合并c[l:m]和c[m+1:r]到d[l:r]
    public void merge(Comparable c[], Comparable d[], int l, int m, int r) {
        int i = 1, j = m + 1, k = l;
        while ((i <= m) && (j <= r)) {
            if (c[i].compareTo(c[j]) <= 0) {
                d[k++] = c[i++];
            } else {
                d[k++] = c[j++];
            }
        }
        if (i > m) {
            for (int q = j; q <= r; q++) {
                d[k++] = c[q];
            }
        } else {
            for (int q = i; q <= m; q++) {
                d[k++] = c[q];
            }
        }

    }

时间复杂度最好最坏平均情况下均为O(nlogn),空间复杂度为O(n),此排序算法稳定
详见算法设计与分析第三版


快速排序

快速排序算法是基于分治策略的另一个排序算法
以a[p]为基准元素将a[p:r]划分为3段:a[p:q-1]、a[q]和a[q+1:r],使得a[p:q-1]中任何元素小于等于a[q],a[q+1:r]中任何元素大于等于a[q]。

//快速排序
    private static void quickSort(int a[], int p, int r) {
        if (p < r) {
            int q = partition(a, p, r);
            quickSort(a, p, q - 1);
            quickSort(a, q + 1, r);
        }
    }

    private static int partition(int a[], int p, int r) {
        int i = p, j = r;
        int x = a[p];
        while (i < j) {
            //从右往左找比x小的数,填充a[i]
            while (i < j && a[j] >= x) j--;
            if (i < j) {
                a[i] = a[j];
            }

            //从左往右找比x大的数,填充a[j]
            while (i < j && a[i] < x) i++;
            if (i < j) {
                a[j] = a[i];
            }
        }
        a[i] = x;
        return i;

    }

基本思路是挖坑填坑,从右往左,找出比基准数小的数填充至a[i],从左往右,找出比基准数大的数填充至a[j],再递归地进行下去
时间复杂度:最坏情况发生在划分过程产生的两个区域分别包含n-1和1个元素的时候,此时的算法复杂度为O(n^2),最好情况是每次划分所取的基准数恰好都为中值,即每次划分都产生两个大小为n/2的区域,此时的时间算法复杂度为O(nlogn),平均时间复杂度为O(nlogn)。
其性能取决于划分的对称性,不稳定
空间复杂度:O(logn)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值