1 归并排序与快速排序的优化

在排序算法的进阶学习中,归并排序和快速排序作为两种经典的排序算法,具有极高的实用价值。它们在实际应用中可以面临多种优化的需求。在本篇教程中,我们将深入探讨这两种排序算法的优化方案,并通过实际案例和代码来阐明这些优化。

归并排序的优化

归并排序简介

归并排序是一种分治算法,其基本思想是将数组分成两半,递归地对左右两部分进行排序,然后将已排序的两部分合并在一起以形成最终的排序结果。其时间复杂度为$O(n \log n)$,但其空间复杂度为$O(n)$,这是其主要的不足之处。

1. 减少空间复杂度

在归并排序中,合并两个已排序数组时会使用额外的数组来存放临时结果。我们可以通过原地合并来优化空间使用。原地合并利用了多种技巧,例如使用双指针的方法来减少空间。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
def merge(arr, left, mid, right):
# 原地合并过程
start = left
end = mid + 1

# 合并两个部分
while start <= mid and end <= right:
if arr[start] <= arr[end]:
start += 1
else:
value = arr[end]
index = end
while index != start:
arr[index] = arr[index - 1]
index -= 1
arr[start] = value

# 更新所有指针
start += 1
mid += 1
end += 1

def merge_sort(arr, left, right):
if left < right:
mid = (left + right) // 2
merge_sort(arr, left, mid)
merge_sort(arr, mid + 1, right)
merge(arr, left, mid, right)

# 测试
arr = [38, 27, 43, 3, 9, 82, 10]
merge_sort(arr, 0, len(arr) - 1)
print(arr) # 输出:[3, 9, 10, 27, 38, 43, 82]

2. 适应性排序

归并排序在已有序的情况下性能表现较差。我们可以实现一种适应性归并排序,在分割和合并的过程中,检查部分数组是否已经有序,以减少不必要的合并操作。

快速排序的优化

快速排序简介

快速排序是一种基于分治策略的排序算法,其核心思想是通过选择一个“基准”(Pivot),将数组分成两个部分,使得左边的元素都小于等于基准,右边的元素都大于等于基准。其平均情况时间复杂度为$O(n \log n)$,但最坏情况为$O(n^2)$,这是需要优化的地方。

1. 改进基准选择

快速排序的性能很大程度上依赖于基准的选择。使用三数取中法选择基准,可以有效避免最坏情况。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def partition(arr, low, high):
mid = low + (high - low) // 2
pivot = sorted([arr[low], arr[mid], arr[high]])[1] # 选择中位数作为基准
pivot_index = arr.index(pivot)

# 移动基准到末尾
arr[pivot_index], arr[high] = arr[high], arr[pivot_index]

i = low - 1
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1

def quick_sort(arr, low, high):
if low < high:
pi = partition(arr, low, high)
quick_sort(arr, low, pi - 1)
quick_sort(arr, pi + 1, high)

# 测试
arr = [10, 7, 8, 9, 1, 5]
quick_sort(arr, 0, len(arr) - 1)
print(arr) # 输出:[1, 5, 7, 8, 9, 10]

2. 小数组的插入排序

对于小数组,使用插入排序可以比快速排序快。因此,当待排序的子数组小于某个阈值时,我们可以切换到插入排序,这样能提高性能。

3. 尾递归优化

快速排序可以通过尾递归的形式进行优化,减少栈深度。每次递归后,只递归较小的部分,减少递归深度,以降低空间复杂度。

总结

在本篇教程中,我们详细探讨了归并排序与快速排序的优化策略,包括减少空间复杂度、改善基准选择、适应性排序和小数组的处理等。这些优化能够有效提高排序算法的性能和应用场景,使其在不同类型的数据处理时更具灵活性和效率。在下一篇教程中,我们将继续讨论桶排序与基数排序的优化,希望你能与我一起学习,加深对排序算法的理解与应用。

1 归并排序与快速排序的优化

https://zglg.work/algorithm-one/1/

作者

IT教程网(郭震)

发布于

2024-08-11

更新于

2024-08-12

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论