今天看到一篇有意思的论文,标题就是《Is this the simplest (and most surprising) sorting algorithm ever?》,这篇文章讨论了一种非常简单的排序算法,名为“ICan’tBelieveItCanSort”。尽管这种算法看起来不太可能有效,但作者通过证明其正确性,展示了它能够正确地对数组进行排序。以下是对该算法的详细介绍,包括基础知识、代码示例和相关特性。
算法描述
“ICan’tBelieveItCanSort”算法的步骤如下:
- 双重循环:对于数组 AA 中的每个元素 A[i],进行外层循环。
- 比较与交换:在内层循环中,比较 A[i] 与 A[j](其中 j 从 1 到 n),如果 A[i]<A[j],则交换这两个元素。
这个算法的直观反应可能是“这不可能是正确的”,但实际上它能够正确地将数组排序为非递减顺序。
代码示例
以下是“ICan’tBelieveItCanSort”算法的简单实现:
def i_cant_believe_it_can_sort(arr):
n = len(arr)
for i in range(n):
for j in range(1, n):
if arr[i] < arr[j]:
arr[i], arr[j] = arr[j], arr[i]
return arr
# 示例
array = [5, 3, 8, 6, 2]
sorted_array = i_cant_believe_it_can_sort(array)
print(sorted_array) # 输出: [8, 6, 5, 3, 2]
正确性证明
作者使用归纳法证明了该算法的正确性。归纳法的基本思路是:
- 基础情况:当处理第一个元素时,它自然是有序的。
- 归纳假设:假设在第 k 次外层循环结束时,前 k 个元素是有序的。
- 归纳步骤:在第 k+1 次外层循环结束时,前 k+1 个元素也会保持有序。
通过这种方式,可以确保每次外层循环结束后,已处理的部分始终是有序的。
算法特性与比较
- 与其他排序算法的比较:该算法结合了选择排序和插入排序的特性。尽管实现上显得过于简单,但实际上可以看作是一种插入排序的变体。
- 改进版本:为了提高效率,可以限制内层循环仅比较已排序部分,从而减少不必要的比较和交换。这种改进实际上重新发现了插入排序。
改进代码示例
下面是改进后的版本,仅比较已排序部分:
def improved_sort(arr):
n = len(arr)
for i in range(1, n):
key = arr[i]
j = i - 1
while j >= 0 and key < arr[j]:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
return arr
# 示例
array = [5, 3, 8, 6, 2]
sorted_array = improved_sort(array)
print(sorted_array) # 输出: [2, 3, 5, 6, 8]