冒泡法的算法最佳情况下的时间复杂度为什么是O(n)
我在许多书本上看到冒泡排序的最佳时间复杂度是O(n),即是在序列本来就是正序的情况下。
但我一直不明白这是怎么算出来的,因此通过阅读《算法导论-第2版》的2.2节,使用对插入排序最佳时间复杂度推算的方法,来计算冒泡排序的复杂度。
1. 《算法导论》2.2中对插入排序最佳时间复杂度的推算

在最好情况下,6和7总不被执行,5每次只被执行1次。因此,

时间复杂度为O(n)
2. 冒泡排序的时间复杂度
2.1 排序代码

public void bubbleSort(int arr[]) {
for(int i = 0, len = arr.length; i < len - 1; i++) {
for(int j = 0; j < len - i - 1; j++) {
if(arr[j + 1] < arr[j])
swap(arr, j, j + 1);
}
}
}

2.2 最佳情况
序列原本就是正序
2.3 最佳情况时间复杂度推算
| 语句 | cost | times |
|
i = 0, len = arr.length |
c1 | 1 |
| i < len - 1 | c2 | n |
| i++ | c3 | n - 1 |
| j = 0 | c4 | n - 1 |
| j < len - i - 1 | c5 | t(i=0) + t(i=1) + ... + t(i = n-2) |
| j++ | c6 | t2(i=0) + t2(i=1) + ... + t2(i = n-2) |
| arr[j + 1] < arr[j] | c7 | t3(i=0) + t3(i=1) + ... + t3(i = n-2) |
| swap(arr, j, j + 1) | c8 | t4(i=0) + t4(i=1) + ... + t4(i = n-2) |
T(n) = c1 + c2n + c3(n - 1) + c4(n - 1) + c5[t1(i=0) + t1(i=1) + ... + t1(i = n-2)] + c6[t2(i=0) + t2(i=1) + ... + t2(i = n-2)] + c7[t3(i=0) + t3(i=1) + ... + t3(i = n-2)] + c8[t4(i=0) + t4(i=1) + ... + t4(i = n-2)];
当序列原本就是正序时,8从不被执行。因此
T(n) = c1 + c2n + c3(n - 1) + c4(n - 1) + c5[t1(i=0) + t1(i=1) + ... + t1(i = n-2)] + c6[t2(i=0) + t2(i=1) + ... + t2(i = n-2)] + c7[t3(i=0) + t3(i=1) + ... + t3(i = n-2)];
此时的时间复杂度应为O(n^2)。
可是网上和许多书上都写道是O(n),不知是否有人能帮我解答一下呢?
2.4 在Stackoverflow上问到答案了。
我原本的代码的时间复杂度确实应该是O(n^2),但算法可以改进,使最佳情况时为O(n)。改进后的代码为:

public void bubbleSort(int arr[]) {
boolean didSwap;
for(int i = 0, len = arr.length; i < len - 1; i++) {
didSwap = false;
for(int j = 0; j < len - i - 1; j++) {
if(arr[j + 1] < arr[j]) {
swap(arr, j, j + 1);
didSwap = true;
}
}
if(didSwap == false)
return;
}
}

冒泡法的算法最佳情况下的时间复杂度为什么是O(n)的更多相关文章
- master公式 ------ 求递归情况下的时间复杂度
剖析递归行为和递归行为时间复杂度的估算一个递归行为的例子T(N) = a*T(N/b) + O(N^d)1) log(b,a) > d -> 复杂度为O(N^log(b,a))2) log ...
- 算法最坏,平均和最佳情况(Worst, Average and Best Cases)-------geeksforgeeks 翻译
最坏,平均和最佳运行时间(Worst, Average and Best Cases) 在上一篇文章中,我们讨论到了渐进分析可以解决分析算法的问题,那么在这一篇中,我们用线性搜索来举例说明一下如何用渐 ...
- C程序数组算法 — 冒泡法排序【前冒 || 后冒】
第一种写法(前冒泡): /* C程序数组算法 - 冒泡法排序 * 此例子按照 大 -> 小 排序 * 原理:两两相比较,然后进行大小对调 * 比较次数: n^2 次 * 说明:冒泡排序是相对稳定 ...
- ruby冒泡算法删除店铺下的重复评论
Shop.each do |shop| if !shop.comments.blank? n = shop.comments.length for i in 0..n-1 for j in i+1.. ...
- MySQL分页优化中的“INNER JOIN方式优化分页算法”到底在什么情况下会生效?
本文出处:http://www.cnblogs.com/wy123/p/7003157.html 最近无意间看到一个MySQL分页优化的测试案例,并没有非常具体地说明测试场景的情况下,给出了一种经典的 ...
- [算法]体积不小于V的情况下的最小价值(0-1背包)
题目 0-1背包问题,问要求体积不小于V的情况下的最小价值是多少. 相关 转移方程很容易想,初始化的处理还不够熟练,可能还可以更简明. 使用一维dp数组. 代码 import java.util.Sc ...
- 冒泡排序最佳情况的时间复杂度,为什么是O(n)
冒泡排序最佳情况的时间复杂度,为什么是O(n) 我在许多书本上看到冒泡排序的最佳时间复杂度是O(n),即是在序列本来就是正序的情况下. 但我一直不明白这是怎么算出来的,因此通过阅读<算法导论-第 ...
- Java温故而知新-冒泡法排序
冒泡法排序是各种初学者在学习数组与循环结构时都会练习的一种简单排序算法. 冒泡法的精髓在于比较相邻的两个元素,较大的元素会不断的排到队伍后面去,就像水里的泡泡一样不断向上跑. 想像一下倒在一个透明玻璃 ...
- "二分法"-"折半法"-查找算法-之通俗易懂,图文+代码详解-java编程
转自http://blog.csdn.net/nzfxx/article/details/51615439 1.特点及概念介绍 下面给大家讲解一下"二分法查找"这个java基础查找 ...
随机推荐
- bzoj1969: [Ahoi2005]LANE 航线规划(树链剖分)
只有删边,想到时间倒流. 倒着加边,因为保证图连通,所以一开始一定至少是一棵树.我们先建一棵树出来,对于每一条非树边,两个端点在树上这段路径的边就不会变成关键边了,所以将它们对答案的贡献删去,那么直接 ...
- Java之面向对象编程20170619
/*************************************************************************************************** ...
- bzoj4774 修路
4774: 修路 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 290 Solved: 137[Submit][Status][Discuss] D ...
- 中南多校对抗赛 第三场 B
B:Arithmetic Progressions 题意: 给你一个长度为n的序列,问你这个序列中长度最长的等差数列长度为多少 题解: 方法一:将数组从小到大排序,n方扫,枚举出公差d,然后二分找有多 ...
- mac pro电脑怎么安装rabbitmq
第一:依次执行以下命令: 1. /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/inst ...
- Python与R的争锋:大数据初学者该怎样选?
在当下,人工智能的浪潮席卷而来.从AlphaGo.无人驾驶技术.人脸识别.语音对话,到商城推荐系统,金融业的风控,量化运营.用户洞察.企业征信.智能投顾等,人工智能的应用广泛渗透到各行各业,也让数据科 ...
- [吴恩达机器学习笔记]14降维5-7重建压缩表示/主成分数量选取/PCA应用误区
14.降维 觉得有用的话,欢迎一起讨论相互学习~Follow Me 14.5重建压缩表示 Reconstruction from Compressed Representation 使用PCA,可以把 ...
- HTML不常用的表单属性-fieldset
这是代码 这是生成的样子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...
- Spring MVC 拦截器配置 -- 利用session
spring-servlet.xml <?xml version="1.0" encoding="UTF-8"?><beans xmlns=& ...
- JAVA中反射机制六(java.lang.reflect包)
一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...