4 排序算法入门

在上一篇中,我们探讨了算法的基础知识和实际应用,了解到算法是解决问题的有效工具。在这一篇中,我们将专注于排序算法,深入了解它们的工作原理及应用场景。排序算法是算法中非常重要的一部分,因为许多实际问题都需要对数据进行排序,而排序结果对于后续的查找和处理往往至关重要。

什么是排序算法?

排序算法是一种将元素进行排列的算法,通常基于某种比较关系。常见的排序算法包括:

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 归并排序
  • 快速排序
  • 堆排序

不同的排序算法在性能、稳定性和适用场景上各有差异,因此选择合适的排序算法非常重要。

常见排序算法介绍

1. 冒泡排序

冒泡排序是一种简单的排序算法,重复地走访要排序的数列,比较每对相邻元素,如果它们的顺序错误就交换它们。

时间复杂度:最坏情况下是 $O(n^2)$
空间复杂度:$O(1)$

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
def bubble_sort(arr):
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j] # 交换
return arr

# 示例
data = [64, 34, 25, 12, 22, 11, 90]
sorted_data = bubble_sort(data)
print(sorted_data) # 输出:[11, 12, 22, 25, 34, 64, 90]

2. 选择排序

选择排序是一种简单直观的排序算法。它的基本思想是每次把未排序的部分中最小的元素选择出来,并把它放到已排序部分的末尾。

时间复杂度:最坏情况下是 $O(n^2)$
空间复杂度:$O(1)$

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def selection_sort(arr):
n = len(arr)
for i in range(n):
min_idx = i
for j in range(i+1, n):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i] # 交换
return arr

# 示例
data = [64, 25, 12, 22, 11]
sorted_data = selection_sort(data)
print(sorted_data) # 输出:[11, 12, 22, 25, 64]

3. 插入排序

插入排序是一种简单的排序算法,它构建一个有序序列,逐步将新元素插入到该序列中,适合数据量较小或基本有序的情况。

时间复杂度:最坏情况下是 $O(n^2)$,最佳情况是 $O(n)$
空间复杂度:$O(1)$

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def insertion_sort(arr):
for i in range(1, len(arr)):
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

# 示例
data = [12, 11, 13, 5, 6]
sorted_data = insertion_sort(data)
print(sorted_data) # 输出:[5, 6, 11, 12, 13]

4. 归并排序

归并排序是一种有效的分治算法,它将一个数组分成两半,分别对这两半进行排序,然后再合并起来。

时间复杂度:最坏和平均情况下都是 $O(n \log n)$
空间复杂度:$O(n)$

代码示例

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
34
35
36
def merge_sort(arr):
if len(arr) > 1:
mid = len(arr) // 2 # 寻找中间点
L = arr[:mid] # 切割成左右两部分
R = arr[mid:]

merge_sort(L) # 递归排序左半部分
merge_sort(R) # 递归排序右半部分

i = j = k = 0

# 合并 L 和 R
while i < len(L) and j < len(R):
if L[i] < R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1

while i < len(L):
arr[k] = L[i]
i += 1
k += 1

while j < len(R):
arr[k] = R[j]
j += 1
k += 1
return arr

# 示例
data = [38, 27, 43, 3, 9, 82, 10]
sorted_data = merge_sort(data)
print(sorted_data) # 输出:[3, 9, 10, 27, 38, 43, 82]

5. 快速排序

快速排序是基于分治法的一种高效排序算法。它通过一个“基准”元素将数组分成两个部分,并递归地对这两个部分进行排序。

时间复杂度:最坏情况下是 $O(n^2)$,最佳情况下是 $O(n \log n)$
空间复杂度:$O(\log n)$

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2] # 选择基准值
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)

# 示例
data = [10, 7, 8, 9, 1, 5]
sorted_data = quick_sort(data)
print(sorted_data) # 输出:[1, 5, 7, 8, 9, 10]

6. 堆排序

堆排序是一种基于比较的排序算法,它利用堆这种数据结构对数据进行排序。堆是一个完全二叉树,且符合

作者

IT教程网(郭震)

发布于

2024-08-11

更新于

2024-08-12

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论