【发布时间】:2022-01-20 19:27:46
【问题描述】:
在尝试排序时,我想出了一种类似于某种插入排序的排序。
不同之处在于,在交换时,我不必比较从元素索引到索引 0 的元素(最坏情况)。
它也类似于分治排序算法,因为它在同一数组中模拟已排序的扇区和未排序的扇区。
我的看法是,最初我会将当前元素指定为第一个元素。 然后我会将当前元素与下一个元素进行比较。如果电流更大,我交换元素。然后我递减以保持当前索引不变。
否则,我会递增以推进当前索引。
这意味着我的电流将始终是最新的参考值。比较的其他值总是较小且已排序。
请参考代码:
#include<stdio.h>
void printArray(int *a, int l)
{
int i = 1;
printf("[%d", a[0]);
while(i < l)
{
printf(", %d", a[i]);
++i;
}
printf("]\n");
}
void whatSort(int *a, int l)
{
int i = 0;
int temp;
while(i < (l - 1))
{
if(*(a + i) > *(a + i + 1))
{
temp = *(a + i);
*(a + i) = *(a + i + 1);
*(a + i + 1) = temp;
--i;
}
else
{
++i;
}
}
}
int main(void)
{
//int array[] = {42, 18, 74, 2, 35, 92, 37, 25};
int array[] = {6, 5, 3, 1, 8, 7, 2, 4};
printArray(array, 8);
whatSort(array, 8);
printArray(array, 8);
return 0;
}
我很确定这种类型(双关语)已经存在,但我无法找到名称。很高兴知道它叫什么。不过,我希望帮助计算仅用于此类的代码段的运行时复杂度。这就是我想出的。任何帮助将不胜感激。
对于这种特殊情况,假设每个操作需要 1 个时间单位。
Declaration
Assignment
Declaration
Loop condition will run l - 1 times:
Comparison
Subtraction
Loop inside code will run l - 2 times:
IF statement:
Dereference
Addition
Comparison
Dereference
Addition
Addition
Assignment
Dereference
Addition
Dereference
Addition
Assignment
Dereference
Addition
Addition
Dereference
Addition
Addition
Assignment
Decrement
OR
ELSE statement:
Increment
最终,我想出 O(n) 其中:
Worst case = 3 + [2 * (l - 1)] + [6 * (l - 2)] + [14 * (l - 2)]
O(22n - 39)
O(n)
Best case = 3 + [2 * (l - 1)] + [6 * (l - 2)] + (l - 2)
O(9n - 13)
O(n)
【问题讨论】:
-
这只是一个非常慢的插入排序,所以 O(n^2)。最坏的情况是一个以相反顺序开始的数组,例如
int array[] = {9,8,7,6,5,4,3,2,1};每次i到达数组排序部分的末尾,算法需要将下一个数字一直带回数组的开头。这就是插入排序的工作方式,但插入排序做得更快。然后该算法会浪费大量时间来查找已排序部分的结尾。插入排序会跟踪已排序部分的末尾在哪里,然后就跳到那里。 -
使用我建议的数组。将
printf("%d\n", i);放在循环的顶部。在此处发布结果。 -
我已经做到了。
i递增,直到到达已排序部分的末尾。然后它递减直到到达数组的开头。 -
想象算法已经进行到数组是
[6,7,8,9,5,4,3,2,1]和i=3和array[i]是9。现在代码比较9 和5,交换它们,并递减i。所以现在array[i]是 8。比较 8 和 5,交换它们,然后递减i。该算法必须一直这样做,直到i为 0,因为 5 必须在排序部分的开头。 -
丹尼斯·里奇有一个绝妙的主意,他决定将
*(a+i)写成a[i]
标签: c algorithm sorting time-complexity big-o