data-structures - 单for循环冒泡排序的时间复杂度
问题描述
我研究了冒泡排序是一种 O(n^2) 算法。但我设计了一个看起来像 O(n) 的算法。以下是我的代码:
void bubbleSort(int[] arr) {
int counter = 1, i = 0;
int N = arr.length-counter;
for(i=0; i<N; ){
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
i++;
if(i == N){
N = arr.length - (++counter);
i = 0;
}
}
有一个 for 循环,当它等于 N 时设置计数器 i。根据我的说法,循环是 O(n),它会重置 n-1 次。因此,它变为 O(n) + O(n-1) = O(n)。我对么?如果不是这个代码的复杂性应该是什么。
解决方案
不,你不正确。有一个循环并不意味着它是O(n)
. 您必须考虑执行了多少步骤。
您的循环在i == N
. 你是对的 - 循环得到重新初始化的(n-1)
时间。现在每个时间循环都执行时间的 then 值N
。因此,O(n) + O(n-1)
最终O(n*(n-1))
导致O(n^2)
.
例如 -
at first pass, loop will be executed (N) times. then N will be re-initialized to (N-1)
at second pass, loop will be executed (N-1) times. then N will be re-initialized to (N-2)
...
...
this will go on in total of (n-1) times.
所以它将是 - O(N + (N - 1) + (N - 2) + ... + 1)
,它将被评估为O(n^2)
出于实验目的,您可以全局初始化计数器。并检查程序执行的总步骤的值是多少,以检查实际发生的情况 -
void bubbleSort(int[] arr) {
int counter = 1, i = 0;
int total = 0;
int N = arr.length-counter;
for(i=0; i<N; ){
total++;
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
i++;
if(i == N){
N = arr.length - (++counter);
i = 0;
}
}
printf(%d", total); // this will give you total number of steps executed. check for various value of n
推荐阅读
- google-sheets - 如何从谷歌表格中列的逗号分隔值创建计数图?
- java - 将 java 字符串转换为扩展 ascii 字符集(代码页 437)
- pandas - 如何在 pandas DF 列中找出哪些值不能使用 astype 函数转换为“int”类型
- scala - 加入大数据帧和小数据帧时的广播数据帧和过滤器
- docker - docker:来自守护进程的错误响应:驱动程序编程外部连接失败
- java - 使用 kill -3 捕获线程转储
- php - 在 Ubuntu 18.04 上使用 php8.0.03 在 apache2 上运行 mongoBD
- flutter - 导入的 mdi 图标未在颤振项目中呈现
- computer-vision - 使用 YOLOv4 进行紧急和非紧急车辆分类
- javascript - js scrollIntoView() 后,asp.net 页面不断重新加载