====== 第十章:高级数据结构 ====== ===== 本章目标 ===== 完成本章学习后,你将能够: * 掌握collections模块的高级数据结构 * 理解栈、队列、双端队列的应用 * 使用堆和优先队列 * 掌握链表的实现和应用 ===== collections模块 ===== ==== Counter计数器 ==== from collections import Counter # 创建计数器 c = Counter(['a', 'b', 'a', 'c', 'a', 'b']) print(c) # Counter({'a': 3, 'b': 2, 'c': 1}) # 从字符串创建 c = Counter("mississippi") print(c) # Counter({'i': 4, 's': 4, 'p': 2, 'm': 1}) # 常用方法 print(c.most_common(2)) # [('i', 4), ('s', 4)],最常见的2个 print(c.elements()) # 迭代所有元素 # 数学运算 c1 = Counter(a=3, b=1) c2 = Counter(a=1, b=2) print(c1 + c2) # Counter({'a': 4, 'b': 3}) print(c1 - c2) # Counter({'a': 2}) ==== defaultdict默认字典 ==== from collections import defaultdict # 默认值为列表 words = ["apple", "bat", "bar", "atom", "book"] by_first_letter = defaultdict(list) for word in words: by_first_letter[word[0]].append(word) print(dict(by_first_letter)) # {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']} # 默认值为整数(计数) counts = defaultdict(int) for word in words: counts[word[0]] += 1 ==== deque双端队列 ==== from collections import deque # 创建 d = deque([1, 2, 3, 4, 5]) # 两端操作(都是O(1)) d.append(6) # 右端添加 d.appendleft(0) # 左端添加 right = d.pop() # 右端移除 left = d.popleft() # 左端移除 # 限制大小(滑动窗口) d = deque(maxlen=3) for i in range(10): d.append(i) print(list(d)) # 始终只保留最后3个元素 # 旋转 d = deque([1, 2, 3, 4, 5]) d.rotate(2) # 向右旋转2位: [4, 5, 1, 2, 3] d.rotate(-1) # 向左旋转1位: [5, 1, 2, 3, 4] ===== 堆和优先队列 ===== import heapq # 创建堆(列表) heap = [] # 添加元素 heapq.heappush(heap, 3) heapq.heappush(heap, 1) heapq.heappush(heap, 4) heapq.heappush(heap, 1) # 弹出最小元素 print(heapq.heappop(heap)) # 1 # 从列表构建堆 data = [3, 1, 4, 1, 5, 9, 2, 6] heapq.heapify(data) # 获取n个最大/最小值 print(heapq.nlargest(3, data)) # [9, 6, 5] print(heapq.nsmallest(3, data)) # [1, 1, 2] # 优先队列应用 tasks = [] heapq.heappush(tasks, (2, "write code")) # (优先级, 任务) heapq.heappush(tasks, (1, "design")) heapq.heappush(tasks, (3, "test")) while tasks: priority, task = heapq.heappop(tasks) print(f"[{priority}] {task}") ===== 链表实现 ===== class Node: """链表节点""" def __init__(self, data): self.data = data self.next = None class LinkedList: """单向链表""" def __init__(self): self.head = None self.size = 0 def append(self, data): """在末尾添加""" new_node = Node(data) if not self.head: self.head = new_node else: current = self.head while current.next: current = current.next current.next = new_node self.size += 1 def prepend(self, data): """在头部添加""" new_node = Node(data) new_node.next = self.head self.head = new_node self.size += 1 def delete(self, data): """删除第一个匹配的节点""" if not self.head: return if self.head.data == data: self.head = self.head.next self.size -= 1 return current = self.head while current.next: if current.next.data == data: current.next = current.next.next self.size -= 1 return current = current.next def find(self, data): """查找节点""" current = self.head index = 0 while current: if current.data == data: return index current = current.next index += 1 return -1 def to_list(self): """转换为Python列表""" result = [] current = self.head while current: result.append(current.data) current = current.next return result # 使用 ll = LinkedList() ll.append(1) ll.append(2) ll.append(3) ll.prepend(0) print(ll.to_list()) # [0, 1, 2, 3] ===== 本章练习 ===== 1. 使用Counter统计文本词频,输出前10 2. 使用deque实现滑动窗口最大值 3. 使用堆合并K个有序列表 4. 实现双向链表 5. 使用优先队列实现任务调度器 下一章:[[python_course:chapter11|第十一章:函数基础]]