一、排序算法:高效数据整理的基石
1. 快速排序(Quick Sort)
作为分治思想的典范,快速排序通过选取基准值(pivot)将数组划分为左右两部分,递归处理子数组。其平均时间复杂度为O(n log n),但最坏情况下(如已排序数组)会退化至O(n²)。优化策略包括随机化基准值、三数取中法等。
def quick_sort(arr):if len(arr) <= 1:return arrpivot = 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)
最佳实践:适用于大规模数据排序,需注意递归深度控制以避免栈溢出。
2. 归并排序(Merge Sort)
采用自底向上的分治策略,将数组拆分为最小单元后合并。时间复杂度稳定为O(n log n),但需要O(n)额外空间。
def merge_sort(arr):if len(arr) <= 1:return arrmid = len(arr)//2left = merge_sort(arr[:mid])right = merge_sort(arr[mid:])return merge(left, right)def merge(left, right):result = []while left and right:if left[0] < right[0]:result.append(left.pop(0))else:result.append(right.pop(0))return result + left + right
适用场景:链表排序、外部排序(大数据量分块处理)。
3. 堆排序(Heap Sort)
基于二叉堆数据结构,通过构建最大堆实现升序排序。时间复杂度O(n log n),空间复杂度O(1)。
def heapify(arr, n, i):largest = il = 2 * i + 1r = 2 * i + 2if l < n and arr[i] < arr[l]:largest = lif r < n and arr[largest] < arr[r]:largest = rif largest != i:arr[i], arr[largest] = arr[largest], arr[i]heapify(arr, n, largest)def heap_sort(arr):n = len(arr)for i in range(n//2 - 1, -1, -1):heapify(arr, n, i)for i in range(n-1, 0, -1):arr[i], arr[0] = arr[0], arr[i]heapify(arr, i, 0)
性能优化:可结合优先队列实现动态数据排序。
二、搜索算法:精准定位目标
4. 二分查找(Binary Search)
针对有序数组,每次将搜索范围减半。时间复杂度O(log n),需注意边界条件处理。
def binary_search(arr, target):left, right = 0, len(arr)-1while left <= right:mid = (left + right) // 2if arr[mid] == target:return midelif arr[mid] < target:left = mid + 1else:right = mid - 1return -1
变种应用:查找第一个/最后一个等于目标的元素、旋转数组搜索。
5. 深度优先搜索(DFS)
通过递归或栈实现图的遍历,适用于连通性检测、拓扑排序等场景。
def dfs(graph, start, visited=None):if visited is None:visited = set()visited.add(start)print(start)for neighbor in graph[start]:if neighbor not in visited:dfs(graph, neighbor, visited)
注意事项:需处理循环引用,避免无限递归。
6. 广度优先搜索(BFS)
使用队列实现层级遍历,常用于最短路径问题(无权图)。
from collections import dequedef bfs(graph, start):visited = set()queue = deque([start])visited.add(start)while queue:vertex = queue.popleft()print(vertex)for neighbor in graph[vertex]:if neighbor not in visited:visited.add(neighbor)queue.append(neighbor)
优化方向:双向BFS可显著提升搜索效率。
三、图论算法:复杂网络解析
7. Dijkstra算法
解决带权有向图的单源最短路径问题,使用优先队列优化后时间复杂度为O((V+E) log V)。
import heapqdef dijkstra(graph, start):distances = {node: float('infinity') for node in graph}distances[start] = 0heap = [(0, start)]while heap:current_dist, current_node = heapq.heappop(heap)if current_dist > distances[current_node]:continuefor neighbor, weight in graph[current_node].items():distance = current_dist + weightif distance < distances[neighbor]:distances[neighbor] = distanceheapq.heappush(heap, (distance, neighbor))return distances
限制条件:不适用于负权边图。
8. 最小生成树(Prim/Kruskal)
Prim算法通过贪心策略逐步扩展生成树,Kruskal算法则按边权排序后合并。
# Kruskal算法示例def find(parent, i):if parent[i] == i:return ireturn find(parent, parent[i])def kruskal(graph):result = []i, e = 0, 0edges = []for u in graph:for v, weight in graph[u].items():edges.append((u, v, weight))edges.sort(key=lambda x: x[2])parent = {}for node in graph:parent[node] = nodewhile e < len(graph)-1 and i < len(edges):u, v, w = edges[i]i += 1x = find(parent, u)y = find(parent, v)if x != y:e += 1result.append((u, v, w))parent[x] = yreturn result
应用场景:网络设计、集群通信优化。
四、动态规划与贪心策略
9. 动态规划(DP)
通过状态转移方程解决重叠子问题,如斐波那契数列计算:
def fib_dp(n):dp = [0]*(n+1)dp[1] = 1for i in range(2, n+1):dp[i] = dp[i-1] + dp[i-2]return dp[n]
优化技巧:空间复杂度可从O(n)降至O(1)(仅保留前两个状态)。
10. 贪心算法
每一步选择局部最优解,如活动选择问题:
def activity_selection(start, finish):activities = sorted(zip(start, finish), key=lambda x: x[1])selected = [activities[0]]last_finish = activities[0][1]for s, f in activities[1:]:if s >= last_finish:selected.append((s, f))last_finish = freturn selected
适用条件:问题具有贪心选择性质(如最优子结构)。
五、算法选择与优化策略
- 数据规模分析:小规模数据优先选择简单算法(如插入排序),大规模数据需考虑时间复杂度。
- 空间权衡:归并排序需额外空间,堆排序则原地操作。
- 稳定性要求:归并排序稳定,快速排序不稳定。
- 并行化潜力:归并排序、矩阵乘法等可拆分为独立子任务。
开发者可通过LeetCode等平台系统练习算法思维,结合具体业务场景(如推荐系统中的相似度计算、日志分析中的Top K查询)灵活应用。掌握这些核心算法,将为解决复杂技术问题提供坚实的理论基础。