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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 时间复杂度 O(n) 级排序算法 -> 正文阅读

[数据结构与算法]时间复杂度 O(n) 级排序算法

《算法导论》定理 8.1:在最坏情况下,任何比较排序算法都需要做 O(nlogn) 次比较。

《算法导论》推论 8.2:堆排序和归并排序都是渐进最优的比较排序算法。

所以时间复杂度 O(n) 级排序算法都是不进行比较的算法而通过元素本身的特性进行排序的算法,因此都有一定的限制,并不是在所有情况都能使用,主要的有:计数排序,基数排序和桶排序。

计数排序

计数排序需要提前知道所有元素的取值范围,比如【0,10】,依据这个范围建立一个数组t[11],并将其全部初始化为0,接下来遍历需要排序的数组,假设遍历到的数字为i,则t[i]++。遍历结束后数组t中每个位置的数字就代表对应元素出现的次数,接下来遍历数组t,并把对应个数的元素放入原数组中。

以上步骤是建立在需要排序的元素是单纯的数字的情况下,如果是一个比较复杂的元素,那么可能需要利用队列或者每次都计算好该元素放入的位置。

数组的相对排序

?

?这道题中元素的范围是比较小的,所以适合使用计数排序。

public class Solution {
    public int[] RelativeSortArray(int[] arr1, int[] arr2) {
        int[] res=new int[arr1.Length];
        int[] num1=new int[1001];
        for(int i=0;i<1001;i++)
        num1[i]=0;
        for(int i=0;i<arr1.Length;i++)
        num1[arr1[i]]++;
        int a=0;
        for(int i=0;i<arr2.Length;i++)
        {
            for(int j=0;j<num1[arr2[i]];j++)
            res[a++]=arr2[i];
            num1[arr2[i]]=0;
        }
        for(int i=0;i<1001;i++)
        {
            if(num1[i]!=0)
            for(int j=0;j<num1[i];j++)
            res[a++]=i;
        }
        return res;
    }
}

基数排序

想一下我们是怎么对日期进行排序的。比如对这样三个日期进行排序:2014 年 11月 7?日,2020 年 1 月 9 日,2020 年 7 月 10 日。

我们大脑中对日期排序的思维过程是:先看年份,2014 比 2020 要小,所以 2014 年这个日期应该放在其他两个日期前面。另外两个日期年份相等,所以我们比较一下月份,1 比 7 要小,所以 1 月这个日期应该放在 7?月这个日期前面。

对一组整数排序也是这样,依次比较各个位上的数字,最后就得到了有序序列。

基数排序分两种,一种是比较符合我们直觉的从高位到低位的比较,另一种则是反过来。实际上算法中常用的是后一种,因为前一种,在每次比较后都要根据结果分为排序完成(该位上仅有这一个数)的和未完成的(该位有多个数)。比如上面的例子中比较完年份后就要把2014 年 1 月 7?日排除,否则根据月份排序它就落到后面了。

如果从低位到高位比较非负整数,步骤是这样的:计算出最大的整数的位数max,建立10个队列,从个位开始,遍历按照该位上的数字把元素放入对应的队列中,遍历结束后按0~9依次出队所有元素,并放回数组中,进行下一位的比较,循环直到最高位。

最大间距

?

?元素的取值范围是比较大的,所以不适合用计数排序。

注意队列数组中的每个都要初始化。

public class Solution {
    public int MaximumGap(int[] nums) {
        if(nums.Length<2)
        return 0;
        Queue<int>[] q = new Queue<int>[10];
        Queue<int> q0 = new Queue<int>();q[0] = q0;
        Queue<int> q1 = new Queue<int>();q[1] = q1;
        Queue<int> q2 = new Queue<int>();q[2] = q2;
        Queue<int> q3 = new Queue<int>();q[3] = q3;
        Queue<int> q4 = new Queue<int>();q[4] = q4;
        Queue<int> q5 = new Queue<int>();q[5] = q5;
        Queue<int> q6 = new Queue<int>();q[6] = q6;
        Queue<int> q7 = new Queue<int>();q[7] = q7;
        Queue<int> q8 = new Queue<int>();q[8] = q8;
        Queue<int> q9 = new Queue<int>();q[9] = q9;
        int maxlv=0;
        for(int i=0;i<nums.Length;i++)
            if(Math.Log10((double)nums[i])>maxlv)
            maxlv=(int)Math.Log10((double)nums[i]);

        sort(nums,q,maxlv);
        int max=0;
        for(int i=1;i<nums.Length;i++)
            if(nums[i]-nums[i-1]>max)
            max=nums[i]-nums[i-1];

        return max;
    }
    public void sort(int[] nums,Queue<int>[] q,int maxlv)
    {
        for(int i=0;i<=maxlv;i++)
        {
            for(int j=0;j<nums.Length;j++)
            q[Level(nums[j],i)].Enqueue(nums[j]);
            int a=0;
            for(int j=0;j<10;j++)
                while(q[j].Count!=0)
                nums[a++]=q[j].Dequeue();
        }
    }
    public int Level(int x,int level)
    {
        return (x/pow10(level))%10;
    }
    public int pow10(int x)
    {
        if(x==0)
        return 1;
        int res=1;
        for(int i=0;i<x;i++)
        res*=10;
        return res;
    }
}

桶排序

桶排序的思想是:

  • 将区间划分为 n 个相同大小的子区间,每个子区间称为一个桶
  • 遍历数组,将每个数字装入桶中
  • 对每个桶内的数字单独排序,这里需要采用其他排序算法,如插入、归并、快排等
  • 最后按照顺序将所有桶内的数字合并起来

桶排序有诸多问题,比如如何划分区间,用什么数据结构储存桶,所以不常使用

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-07 22:56:50  更:2022-04-07 22:58:07 
 
开发: 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/26 9:39:23-

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