第十章 搜索与排序算法
10.1 线性搜索
原理:
遍历集合中的每个元素,直到找到目标值。
时间复杂度:
-
最坏情况:O(n)
-
适用场景:无序小规模数据
def linear_search(arr, target):
for idx, val in enumerate(arr):
if val == target:
return idx
return -1
# 示例
print(linear_search([5, 2, 9, 1, 7], 9)) # 输出索引2
10.2 二分搜索
原理:
通过不断缩小搜索范围至一半来定位目标,要求数据有序。
时间复杂度:
-
平均/最坏:O(log n)
def binary_search(arr, target):
left, right = 0, len(arr)-1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# 示例
sorted_arr = sorted([30, 10, 50, 20])
print(binary_search(sorted_arr, 20)) # 输出索引1
冒泡排序:
相邻元素两两比较并交换,逐步将最大值“冒泡”到末尾。
时间复杂度:O(n²)
def bubble_sort(arr):
n = len(arr)
for i in range(n-1):
for j in range(n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
print(bubble_sort([3, 1, 4, 2])) # [1, 2, 3, 4]
10.4 高效排序算法
快速排序:
分治法策略,选取基准值将数据分为左右子数组递归排序。
时间复杂度:
-
平均:O(n log n)
-
最坏:O(n²)
def binary_search(arr, target):
left, right = 0, len(arr)-1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# 示例
sorted_arr = sorted([30, 10, 50, 20])
print(binary_search(sorted_arr, 20)) # 输出索引1
10.5 合并排序
分治三步法:
-
分:递归拆分数组至单个元素
-
治:两两合并有序子数组
-
合:合并结果
时间复杂度:稳定O(n log n)
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
print(merge_sort([38, 27, 43, 3, 9, 82])) # [3, 9, 27, 38, 43, 82]
10.6 小结
核心要点对比:
算法 | 时间复杂度 | 空间复杂度 | 稳定性 | 适用场景 |
---|---|---|---|---|
线性搜索 | O(n) | O(1) | - | 无序小数据 |
二分搜索 | O(log n) | O(1) | - | 有序数据 |
冒泡排序 | O(n²) | O(1) | 稳定 | 教学示例 |
快速排序 | O(n log n) 平均 | O(log n) | 不稳定 | 通用数据 |
合并排序 | O(n log n) | O(n) | 稳定 | 大数据/外部排序 |
开发建议:
-
优先使用内置函数:Python的
list.sort()
和sorted()
基于Timsort(混合合并+插入排序),时间复杂度O(n log n) -
数据量<1000时,简单排序(如插入排序)可能更高效
-
需要稳定性时选择合并排序
-
内存受限场景避免合并排序
示例选择策略:
if data_sorted:
binary_search(data, target)
else:
if len(data) < 1000:
data.sort() # 原址排序
else:
data = sorted(data) # 生成新数组
binary_search(data, target)