热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

时间复杂度_排序算法线性时间复杂度

篇首语:本文由编程笔记#小编为大家整理,主要介绍了排序算法-线性时间复杂度相关的知识,希望对你有一定的参考价值。  一说到排序算法,大部分人都会说

篇首语:本文由编程笔记#小编为大家整理,主要介绍了排序算法-线性时间复杂度相关的知识,希望对你有一定的参考价值。


    一说到排序算法,大部分人都会说出著名的万金油-快速排序、大数据分而治之-归并排序、大数据排名-堆排序。这些排序无论在面试还是实际项目中,都是经常用到的一些排序算法,其平均时间复杂度都在 O(N • log2N),那今天我们就来介绍几种 O(N)的排序算法。

    1,计数排序,输入 n 个范围在 0-k 区间的元素,当 !k >> n 时,排序的运行时间为 O(N)

          论点:对于输入的任一的元素 x,如果有 s 个元素小于,则元素 x 就可以放在 s+1 的位置上,这个时间复杂度近乎 O(1),我们仅需要得出对于每个元素有多少个小于的元素的列表即可在很短的时间内排序完成。

          a.对原数组进行遍历,计算每个元素出现的次数,时间复杂度 O(N),空间复杂度 O(K)

            原数组

            技术图片

 

     额外记录表,下标为元素,值代表出现的次数技术图片

         b,将记录的数组进行计算整理,数组中每个值代表小于当前下标的元素个数,时间复杂度O(K)

额外记录表,下标为元素,值代表小于当前下标的元素个数

技术图片

 

         c.遍历原数组,并按最初提出的论点,进行最终的排序放置到最终数组,并更新记录表中的数值(v-1),时间复杂度O(N) * O(1),空间复杂度O(N)

技术图片

 

         综上所述,所需要的时间复杂度为O(N) + O(K) + O(N)*O(1) = O(N + K),当元素的取值范围较小时,可以达到 O(N)的时间复杂度,空间复杂度为O(N) + O(K) = O(N)

    2,基数排序,建立在计数排序(发现两种排序的谐音完全一样^_^)的基础上,所以请耐心阅读上一段的流程。

          论点:在实际项目过程中,我们需要排序的元素通常很难是在极小范围,这里我们可以利用位数的分隔,首先对所有数值的个位数进行计数排序,以此类推对十位、百位、千位。可以预见我们仅需要对当前元素组进行最大元素的位数次计数排序即可

                     假定最大元素为 x,则进行的计数排序个数为 r = ceil(ln(x)) 取上整数,每次计数排序的时间复杂度为 O(N + K) = O(N + 10) 整个算法复杂度为 ceil(ln(x)) * O(N + 10),所以当最大一位的位数不会超过 ln(N),则整个排序算法的复杂度为 常数 * O(N + 10) = O(N),这种排序算法一般已经可以应用         到很多项目场景中了,只是因为其编码的复杂度和现代计算机的 cpu 性能提高,所以除非巨量的数据排序,否则一般还是会采用快速排序

技术图片

 

    3,桶排序,与基数排序是相反的思路,先生成 n 个相同大小的子区间(桶),将所有元素分到所属的桶内,并按插入排序的方式,放入所属的桶里,时刻保证每个桶内部的数据是有序的。

          论点:只要数据处于散列数据,可以预见每个桶的数据不会太多,除非极端情况下,但只要保证桶的个数,同样可以保证算法的线性时间复杂度(这里先不谈这种情况,这种已经类似于数值与数组下标逆向,需要消耗大量的空间);

          a.生成 n 个桶,并设定每个桶的取值范围(可以去最大值后,向 n 倍数取上整,便于 hash 计算),时间复杂度 O(N),空间复杂度O(N),

          b.遍历整个数组,将元素放入所属桶,并根据插入排序保持桶的有序,时间复杂度 ∑n-1i=0(啊~!不会用这个数学符号编辑啊)O(ni2),其中 ni 表示每次插入排序时当前桶的数量。

          综上所述,时间复杂度的总时间为 O(N) + ... 上面的数学公式,以后学会怎么编辑再来修改。当数据服从均匀分布时,每次的插入排序期望值为 n*O(2-1/N),验证较为复杂,有兴趣的同学可以参考算法导论.114页。

          可以得出时间复杂度为 O(N)

 

 

 

 

 

 

 

 

 

 

 

 

 

 


推荐阅读
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 机器学习中的相似度度量与模型优化
    本文探讨了机器学习中常见的相似度度量方法,包括余弦相似度、欧氏距离和马氏距离,并详细介绍了如何通过选择合适的模型复杂度和正则化来提高模型的泛化能力。此外,文章还涵盖了模型评估的各种方法和指标,以及不同分类器的工作原理和应用场景。 ... [详细]
  • 本文探讨了如何在编程中正确处理包含空数组的 JSON 对象,提供了详细的代码示例和解决方案。 ... [详细]
  • 汇编语言等号伪指令解析:探究其陡峭的学习曲线
    汇编语言以其独特的特性和复杂的语法结构,一直被认为是编程领域中学习难度较高的语言之一。本文将探讨汇编语言中的等号伪指令及其对初学者带来的挑战,并结合社区反馈分析其学习曲线。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本文详细介绍了 React 中的两个重要 Hook 函数:useState 和 useEffect。通过具体示例,解释了如何使用它们来管理组件状态和处理副作用。 ... [详细]
author-avatar
in冷霜天
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有