[想法] 看来确实记牢了。

时隔一个月再次默写快排、堆排、归并排序和希尔排序并成功通过 luogu P1177 排序模板。

虽然现在基本上不需要手写排序了,但理解它们的思想对于写其他的代码也是很有帮助的。

在这之前,我无法凭空写出它们中的任何一种。快排的话只知道用 pivot 但不知道具体怎么划分;堆排的话压根不清楚堆的概念,还以为是堆就是二叉排序树;归并排序只知道怎么并却写不来递归;希尔排序更是闻所未闻,甚至把它和量子编程里面的秀尔算法混在了一起。

最后评价一下这四种算法。

首先,快排的速度就如同它的名称一样快,不仅仅是高贵的原地排序,而且局部性也很好,代码也不复杂,只需要付出一点小小的栈空间代价。

然后是堆排,同样很快而且是原地排序,也很好写,只是局部性不太好。

归并排序对于不支持 ++ 运算符的语言来说略复杂。它的优点在于稳定,而且还能分段处理输入,使得外部排序成为可能。

希尔排序有点玄学,时间复杂度据增量的变化策略而变化,不过用起来效果挺好,在数据量不是特别大的情况下,实测和快排持平。代码量非常短,可以称之为排序算法中的 floyd(不考虑冒泡、选排等平方复杂度排序算法)。

import sys, random
input = sys.stdin.readline
def partition(v: list, L, R) -> tuple:
pivot = v[random.randint(L, R)]
i, j, k = L, L, R + 1
while i < k:
if v[i] == pivot:
i += 1
elif v[i] < pivot:
v[i], v[j] = v[j], v[i]
i += 1
j += 1
else:
k -= 1
v[i], v[k] = v[k], v[i]
return j - 1, k
def quick_sort(v: list, L, R):
if L < R:
l, r = partition(v, L, R)
quick_sort(v, L, l)
quick_sort(v, r, R)
def shell_sort(v: list, L, R):
d = (R - L + 1) // 2
while d != 0:
for i in range(L + d, R + 1):
t = v[i]
j = i - d
while j >= L and v[j] > t:
v[j + d] = v[j]
j -= d
v[j + d] = t
d >>= 1
def heap_sort(v: list):
n = len(v)
for i in range(n // 2, 0, -1):
sift_down(v, i, n)
for i in range(n - 1, 0, -1):
v[i], v[0] = v[0], v[i]
sift_down(v, 1, i)
def sift_down(v: list, L, R):
C = L * 2
while C <= R:
if C + 1 <= R and v[C] > v[C - 1]:
C += 1
if v[C - 1] > v[L - 1]:
v[L - 1], v[C - 1] = v[C - 1], v[L - 1]
else:
break
L = C
C = L * 2
def merge(v: list, L, R):
t = [0] * (R - L + 1)
M = (L + R) // 2
i, j, k = L, M + 1, 0
while i <= M and j <= R:
if v[i] <= v[j]:
t[k] = v[i]
i += 1
else:
t[k] = v[j]
j += 1
k += 1
while i <= M:
t[k] = v[i]
i += 1
k += 1
while j <= R:
t[k] = v[j]
j += 1
k += 1
v[L : R + 1] = t
def merge_sort(v: list, L, R):
if L < R:
M = (L + R) // 2
merge_sort(v, L, M)
merge_sort(v, M + 1, R)
merge(v, L, R)
def solve():
n = int(input())
v = list(map(int, input().split()))
algo = random.randint(1, 4)
if algo == 1:
quick_sort(v, 0, n - 1)
elif algo == 2:
heap_sort(v)
elif algo == 3:
shell_sort(v, 0, n - 1)
else:
merge_sort(v, 0, n - 1)
print(" ".join(map(str, v)))
solve()
posted @   ZXPrism  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示