Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Heap Queue Algorithm ใน Python (โมดูล heapq)

โมดูล heapq ให้ Min-Heap Implementation (Priority Queue) บน List ทำให้ Pop Minimum ได้ O(log n)

import heapq


หลักการ Min-Heap

  • Root = Minimum Element (Priority 1 = สูงสุด)
  • Parent ≤ Children เสมอ
  • เก็บใน List แบบ Complete Binary Tree

ฟังก์ชันหลัก

FunctionคำอธิบายComplexity
heapify(x)แปลง List -> Heap (In-place)O(n)
heappush(heap, item)Push Item + Re-heapO(log n)
heappop(heap)Pop & Return Min Item + Re-heapO(log n)
heappushpop(heap, item)Push แล้ว Pop (Atomic, Fast)O(log n)
heapreplace(heap, item)Pop แล้ว Push (Atomic, Fast)O(log n)
nlargest(n, iterable, key=None)N Largest ElementsO(n log k)
nsmallest(n, iterable, key=None)N Smallest ElementsO(n log k)

โค้ดตัวอย่าง

import heapq

data = [58, 41, 12, 17, 89, 65, 23, 20, 10, 16, 17, 19]

# 1. Heapify
heapq.heapify(data)
print("Heapified:", data)
# [10, 16, 12, 17, 17, 19, 23, 20, 41, 89, 58, 65]

# 2. Push
heapq.heappush(data, 7)
print("After push 7:", data)
# [7, 16, 10, 17, 17, 12, 23, 20, 41, 89, 58, 65, 19]

# 3. Pop
popped = heapq.heappop(data)
print(f"Popped: {popped}, Heap: {data}")
# Popped: 7

# 4. nlargest / nsmallest
print("4 Largest:", heapq.nlargest(4, data))
print("3 Smallest:", heapq.nsmallest(3, data))

ผลลัพธ์

Heapified: [10, 16, 12, 17, 17, 19, 23, 20, 41, 89, 58, 65]
After push 7: [7, 16, 10, 17, 17, 12, 23, 20, 41, 89, 58, 65, 19]
Popped: 7
Heap: [10, 16, 12, 17, 17, 19, 23, 20, 41, 89, 58, 65]
4 Largest: [89, 65, 58, 41]
3 Smallest: [10, 12, 16]

Priority Queue Pattern (Tuple: Priority, Data)

import heapq

pq = []
heapq.heappush(pq, (2, 'Low Priority Task'))
heapq.heappush(pq, (1, 'High Priority Task'))
heapq.heappush(pq, (3, 'Background Task'))

while pq:
    priority, task = heapq.heappop(pq)
    print(f"Priority {priority}: {task}")

# Output:
# Priority 1: High Priority Task
# Priority 2: Low Priority Task
# Priority 3: Background Task

Max-Heap (Python มีแค่ Min-Heap)

# วิธี 1: Negate Values
max_heap = []
for x in [5, 1, 9, 3]:
    heapq.heappush(max_heap, -x)
print(-heapq.heappop(max_heap))  # 9

# วิธี 2: Custom Key (Python 3.11+)
# heapq.heappush(heap, item, key=lambda x: -x)

การประยุกต์ใช้จริง

  • Dijkstra/A* Pathfinding: Priority Queue
  • Task Scheduler: Cron-like, Delayed Execution
  • Streaming Top-K: nlargest/nsmallest บน Data Stream
  • Huffman Coding: Merge Smallest Frequencies
  • K-way Merge: Merge K Sorted Lists

K-way Merge Example

import heapq

def merge_k_sorted(lists):
    heap = []
    for i, lst in enumerate(lists):
        if lst:
            heapq.heappush(heap, (lst[0], i, 0))
    
    result = []
    while heap:
        val, list_idx, elem_idx = heapq.heappop(heap)
        result.append(val)
        if elem_idx + 1 < len(lists[list_idx]):
            next_val = lists[list_idx][elem_idx + 1]
            heapq.heappush(heap, (next_val, list_idx, elem_idx + 1))
    return result

print(merge_k_sorted([[1,4,7], [2,5,8], [3,6,9]]))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]