菜单
×
   ❮   
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

DSA 计数排序时间复杂度


有关时间复杂度的通用解释,请参阅此页面


计数排序时间复杂度

计数排序的工作原理是首先计算不同值的出现次数,然后利用这些次数来按排序顺序重构数组。

经验法则是,当可能值的范围 \(k\) 小于值的数量 \(n\) 时,计数排序算法的运行速度很快。

要使用大 O 表示法表示时间复杂度,我们首先需要计算算法执行的操作数。

  • 查找最大值:必须对每个值进行一次评估,以确定它是否为最大值,因此需要 \(n\) 次操作。
  • 初始化计数数组:在数组中的最大值为 \(k\) 的情况下,我们需要 \(k+1\) 个元素在计数数组中,以便包含 0。计数数组中的每个元素都必须初始化,因此需要 \(k+1\) 次操作。
  • 我们要排序的每个值都会被计数一次,然后删除,因此每次计数需要 2 次操作,总共 \(2 \cdot n\) 次操作。
  • 构建排序数组:创建排序数组中的 \(n\) 个元素:\(n\) 次操作。

总计我们得到

\[ \begin{equation} \begin{aligned} 操作 {} & = n + (k+1) + (2 \cdot n) + n \\ & = 4 \cdot n + k + 1 \\ & \approx 4 \cdot n + k \end{aligned} \end{equation} \]

根据我们之前对时间复杂度的了解,我们可以创建一个简化的表达式,使用大 O 表示法来表示时间复杂度。

\[ \begin{equation} \begin{aligned} O(4 \cdot n + k) {} & = O(4 \cdot n) + O(k) \\ & = O(n) + O(k) \\ & = \underline{\underline{O(n+k)}} \end{aligned} \end{equation} \]

正如前面所提到的,计数排序在不同值的范围 \(k\) 相对于要排序的值的总数 \(n\) 较小时是有效的。我们现在可以直接从大 O 表达式 \(O(n+k)\) 中看出这一点。

例如,假设不同数字的范围 \(k\) 是要排序的值的数量的 10 倍。在这种情况下,我们可以看到算法花费了大部分时间来处理不同数字的范围 \(k\),尽管要排序的实际值 \(n\) 相比较小。

对于计数排序,在图表中显示时间复杂度或进行时间复杂度模拟并不直接,因为时间复杂度受到值范围 \(k\) 的很大影响。

下面是一个图表,显示了计数排序的时间复杂度可能有多大差异,随后是对最佳和最坏情况的解释。

Time Complexity

计数排序的最佳情况是范围 \(k\) 仅占 \(n\) 的一小部分,例如 \(k(n)=0.1 \cdot n\)。例如,对于 100 个值,范围是从 0 到 10;或者对于 1000 个值,范围是从 0 到 100。在这种情况下,我们得到时间复杂度 \(O(n+k)=O(n+0.1 \cdot n) = O(1.1 \cdot n)\),简写为 \(O(n)\)。

然而,最坏情况是范围远大于输入。假设对于仅 10 个值的输入,范围在 0 到 100 之间;或者类似地,对于 1000 个值的输入,范围在 0 到 1000000 之间。在这种情况下,\(k\) 的增长相对于 \(n\) 是二次的,如下所示:\(k(n)=n^2\),我们得到时间复杂度 \(O(n+k)=O(n+n^2)\),简写为 \(O(n^2)\)。甚至比这更糟糕的情况也可能出现,但选择这种情况是因为它相对容易理解,而且也许并不那么不现实。

正如你所看到的,在选择计数排序作为你的算法之前,考虑值的范围与要排序的值的数量进行比较是很重要的。此外,如页面顶部所述,请记住计数排序仅适用于非负整数值。


计数排序模拟

运行计数排序的不同模拟,以了解操作次数如何在最坏情况 \(O(n^2)\)(红线)和最佳情况 \(O(n)\)(绿线)之间变化。

{{ this.userX }}

{{ this.userK }}

操作次数:{{ operations }}

 

如前所述:如果要排序的数字值变化很大(\(k\) 大),而要排序的数字很少(\(n\) 小),则计数排序算法无效。

如果我们保持 \(n\) 和 \(k\) 固定,模拟中的“随机”、“降序”和“升序”选项会导致相同数量的操作。这是因为在这三种情况中发生的事情是相同的:设置一个计数数组,对数字进行计数,然后创建新的排序数组。



×

联系销售

如果您想将 W3Schools 服务用于教育机构、团队或企业,请发送电子邮件给我们
sales@w3schools.com

报告错误

如果您想报告错误,或想提出建议,请发送电子邮件给我们
help@w3schools.com

W3Schools 经过优化,旨在方便学习和培训。示例可能经过简化,以提高阅读和学习体验。教程、参考资料和示例会不断审查,以避免错误,但我们无法保证所有内容的完全正确性。使用 W3Schools 即表示您已阅读并接受我们的使用条款Cookie 和隐私政策

版权所有 1999-2024 Refsnes Data。保留所有权利。W3Schools 由 W3.CSS 提供支持