IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【数据结构与算法】四、排序算法总结 -> 正文阅读

[数据结构与算法]【数据结构与算法】四、排序算法总结

前言

大家好,我是春风。

截止目前,是看左神算法视频的第二周,虽然进度不太快,但还是认真看完了视频,并通过输出文章,做了自己的理解。

目前所谓的十大排序除了桶排序外,已全部完结,今天先补一个桶排序,然后就来总结一下所有的排序算法!

补一个桶排序

和冒泡、选择这种基于两个数比较的排序不同,桶排序不是基于两个数比较的排序,而更是像找同类的方式。

桶排序可以分为计数排序和基数排序两种

计数排序:

当数据量比较小时,且有很多重复数据,就可以使用计数排序,类似于词频统计

  1. 根据数据情况,准备好一系列排好序的桶
  2. 遍历数组,将同样的数放到一个桶里 -?入桶
  3. 最后遍历桶中每个元素,计算他的下标 -?出桶

基数排序

基数排序就是把每个数字拆分个位数字、十位数字、百位数字...依次按顺序入桶出桶,因为最高位最后排,所以优先级最高,而且还能继承之前低位的顺序,所以就能保证整体有序。

因此基数排序只能用于全是数字的情况。

代码:

public static void radixSort(int[] arr) {
    radixSort(arr, 0, arr.length-1, maxbits(arr));
}

public static int maxbits(int[] arr) {
    // 找出最大的数
    int max = Integer.MIN_VALUE;
    for (int i=0; i<arr.length; i++) {
        max = Math.max(max, arr[i]);
    }

    int res = 0;

    // 从最大的数找最多有多少位数
    while (max !=0) {
        res ++;
        max /= 10;
    }

    return res;
}

public static void radixSort(int[] arr, int l, int r, int digit) {
    final int radix = 10;
    int i=0, j=0;

    // 辅助空间
    int[] bucket = new int[r-l+1];

    for(int d=1; d<=digit;d++) {
        // 有多少位,就进出桶多少次
        int[] count = new int[radix];
        for (i=l; i<= r; i++) {
            j = getDigit(arr[i], d);
            count[j]++;
        }
        
        for (i=1; i<radix;i++) {
            count[i] = count[i] + count[i-1];
        }
        for (i =r;i>=l;i--) {
            j = getDigit(arr[i],d);
            bucket[count[j]-1] = arr[i];
            count[j]--;
        }
        
        for(i=l,j=0;i<=r;i++,j++) {
            arr[i]=bucket[j];
        }
    }
}

排序算法总结

我们在学习所有排序算法的时候,每个算法的时间复杂度和空间复杂度都是我们最关心的内容,而且在时间不可再生、空间可叠加的现实面前,时间复杂度往往比空间复杂度优先级更高。

但是我们其实还遗漏了一项参考指标,就是稳定性

什么是稳定性指值相同的情况下,排完序,相同的值是否还能保持原来的相对顺序

这种稳定性的要求,在我们前面经常举例的对基础类型的值做排序的场景中基本不需要考虑,但是很多非基础类型的值做排序的场景确是需要我们考虑的。

比如淘宝对商品做排序,先根据价格排,然后再根据销量排,这种排序的合并,如果我们在第二、三次的排序打乱了原来的顺序,就不满足需求。

计数排序和基数排序也是稳定的,先入先出

时间复杂度空间复杂度稳定性
选择排序O(N^2)O(1)
冒泡排序O(N^2)O(1)是(相等时不交换)
插入排序O(N^2)O(1)
归并排序O(N*logN)O(N)是(相等时先拷贝左边的)
快排排序(随机数版本)O(N*logN)O(logN)
堆排序O(N*logN)O(1)

结论:

  1. 综上考虑,一般情况下,我们选择使用快排,是时间和空间复杂度最低的。
  2. 基于比较的排序,像选择、冒泡、插入,在不增加空间的情况下,还不能做到时间复杂度在O(N*logN)以下。
  3. 奇数放左边,偶数放右边的排序,奇数偶数还要保持稳定性,额外空间复杂度O(logN)的情况下,参考快排的0-1分区,基本做不到。

工程上对排序的改进:

  1. 利用O(NlogN)和O(N^2)排序的各自的优势,大样本时,采用O(NlogN)算法的分区调度,当分区内样本量小时,又采用O(N^2)的排序。(小样本常数项操作的时间低)
  2. Arrays.sort()对类型的判断,如果是基础类型,就考虑用不需要稳定性的排序,否则就用需要稳定性的排序

最后的最后,求点赞!非常感谢!

我是春风,春风和煦,不负归期! 公H:程序员春风

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 23:13:18  更:2022-07-04 23:13:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:18:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码