Data structures (with python) - 3. Heap

2024. 1. 5. 22:00ㆍCS - Roadmap.sh/1. Data structures

Data structures (with python) - 3. Heap

 

πŸ’‘ Heap is a tree-based data structure that follows the properties of a complete binary tree and is either a Min Heap or a Max Heap.

νž™μ€ μ™„μ „ν•œ 이진 트리의 속성을 λ”°λ₯΄λŠ” 트리 기반 데이터 ꡬ쑰둜, μ΅œμ†Œ νž™ λ˜λŠ” μ΅œλŒ€ νž™ 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.

 

νž™(Heap)은 μ΄μ§„νŠΈλ¦¬μ˜ μΌμ’…μœΌλ‘œ, νŠΉμ •ν•œ κ·œμΉ™μ„ 가지고 μžˆλŠ” 자료 ꡬ쑰이닀.

(Tree λŠ” μ΄μ§„νŠΈλ¦¬, 밸런슀 트리, μ–Έλ°ΈλŸ°μŠ€ 트리 등등을 μ°¨ν›„ 닀룬닀.)

 

νž™μ€ 두가지 μ’…λ₯˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.

 

μ΅œλŒ€ νž™(Max heap) , μ΅œμ†Œ νž™(Min Heap)

 

μ΅œλŒ€ νž™ : λΆ€λͺ¨ λ…Έλ“œμ˜ ν‚€ 값이 μžμ‹ λ…Έλ“œμ˜ ν‚€ 값보닀 항상 ν¬κ±°λ‚˜ κ°™λ‹€.

= 즉, 루트 λ…Έλ“œκ°€ κ°€μž₯ 큰 값을 가진닀.

 

μ΅œμ†Œ νž™: λΆ€λͺ¨ λ…Έλ“œμ˜ ν‚€ 값이 μžμ‹ λ…Έλ“œμ˜ ν‚€ 값보닀 항상 μž‘κ±°λ‚˜ 가탇.

= 즉, 루트 λ…Έλ“œκ°€ κ°€μž₯ μž‘μ€ 값을 가진닀.

 

νž™μ€ μš°μ„ μˆœμœ„ 큐(Queue)λ₯Ό κ΅¬ν˜„ν•˜λŠ”λ° 주둜 μ‚¬μš©λ˜λ©°, 이외에도 νž™ μ •λ ¬, κ·Έλž˜ν”„ μ•Œκ³ λ¦¬μ¦˜ λ“± λ‹€μ–‘ν•œ 곳에 ν™œμš©λœλ‹€.

(큐(Queue) λŠ” FIFO(First In, First Out) ꡬ쑰λ₯Ό 가진 μžλ£Œκ΅¬μ‘°μ΄λ‹€. 쀄을 μ„œλŠ” 것과 μœ μ‚¬ν•˜λ©° μ°¨ν›„ 닀룬닀.)

 

 

νŒŒμ΄μ¬μ—μ„œ νž™(Heap)을 κ΅¬ν˜„ν•΄λ³΄λ €λ©΄ heapq λͺ¨λ“ˆλ‘œ μ‰½κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

import heapq

heap = []

 heapq λͺ¨λΈμ€ 기본적으둜 μ΅œμ†Œ νž™μ„ μ œκ³΅ν•œλ‹€.

 

이제 νž™μ— μ›μ†Œλ₯Ό μ‘°μž‘ν•΄λ³΄μž.

 

# νž™μ— μ›μ†Œ μΆ”κ°€
heapq.heappush(heap, 4)
heapq.heappush(heap, 1)
heapq.heappush(heap, 7)
print(heap)  # 좜λ ₯: [1, 4, 7]

# νž™μ— μ›μ†Œ μ‚­μ œ
print(heapq.heappop(heap))  # κ°€μž₯ μž‘μ€ μ›μ†Œ μ‚­μ œ ν›„ 좜λ ₯: 1
print(heap)  # 좜λ ₯: [4, 7]


# κΈ°μ‘΄ 리슀트λ₯Ό νž™μœΌλ‘œ λ³€ν™˜
nums = [4, 1, 7, 3, 8, 5]
heapq.heapify(nums)
print(nums)  # 좜λ ₯: [1, 3, 5, 4, 8, 7]

 

μ£Όμ˜μ μ€ heapq λͺ¨λ“ˆμ€ μ΅œμ†Œ νž™λ§Œμ„ μ§€μ›ν•˜λ―€λ‘œ,

μ΅œλŒ€ νž™μ„ κ΅¬ν˜„ν•˜λ €λ©΄ μ›μ†Œμ˜ λΆ€ν˜Έλ₯Ό λ°”κΏ”μ„œ λ„£κ³  κΊΌλ‚Ό λ•Œ λ‹€μ‹œ λ°”κΏ”μ£ΌλŠ” 방법을 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

 

μ–Έμ œ μ΅œλŒ€ νž™μ„ μ‚¬μš©ν• κΉŒ?

μ›μ†Œλ“€ μ€‘μ—μ„œ κ°€μž₯ 큰 μ›μ†Œλ₯Ό λΉ λ₯΄κ²Œ(!) μ°Ύμ•„μ•Ό ν•  κ²½μš°μ΄λ‹€.

이런 κ²½μš°μ—λŠ” μ΅œλŒ€ νž™(Max heapq)을 κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ”λ°, heapq λͺ¨λ“ˆμ€ μ΅œλŒ€ νž™μ„ μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€.

 

이런 μƒν™©μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” κ°„λ‹¨ν•œ 방법은

μ›μ†Œμ— νž™μ„ μΆ”κ°€ν•  λ•Œ κ·Έ κ°’μ˜ λΆ€ν˜Έλ₯Ό λ°”κΎΈμ–΄ λ„£λŠ” 것이닀.

즉, μ–‘μˆ˜λ₯Ό 음수둜, 음수λ₯Ό μ–‘μˆ˜λ‘œ λ°”κΎΈμ–΄ λ„£λŠ”λ‹€.

 

그러면 μ›λž˜ κ°€μž₯ 큰 μ›μ†Œκ°€ κ°€μž₯ μž‘μ€ κ²ƒμœΌλ‘œ κ°„μ£Ό, νž™μ˜ 루트 λ…Έλ“œμ— 였게 λœλ‹€.

μ›μ†Œλ₯Ό κΊΌλ‚Ό λ–„λŠ” λ‹€μ‹œ λΆ›λ₯Ό λ°”κΏ” μ›λž˜μ˜ 값을 μ–»λŠ”λ‹€.

 

import heapq

nums = [4, 1, 7, 3, 8, 5]
heap = []

# μ›μ†Œλ₯Ό νž™μ— μΆ”κ°€ν•  λ•Œ λΆ€ν˜Έλ₯Ό λ°”κΏ”μ„œ λ„£μŒ
for num in nums:
    heapq.heappush(heap, -num)

# μ›μ†Œλ₯Ό κΊΌλ‚Ό λ•Œ λΆ€ν˜Έλ₯Ό λ‹€μ‹œ λ°”κΏ” μ›λž˜μ˜ 값을 μ–»μŒ
print(-heapq.heappop(heap))  # 좜λ ₯: 8
print(-heapq.heappop(heap))  # 좜λ ₯: 7

 

 

 

Heap κ³Ό κ΄€λ ¨λœ μ•Œκ³ λ¦¬μ¦˜

 

1. νž™ μ •λ ¬(Heap sort)

 μ΅œλŒ€ νž™μ„ κ΅¬μ„±ν•œ ν›„, νž™μ˜ 루트 λ…Έλ“œ(μ΅œλŒ€κ°’)λ₯Ό λ°°μ—΄ λ§ˆμ§€λ§‰ μš”μ†Œμ™€ κ΅ν™˜, νž™μ˜ 크기λ₯Ό 1 쀄인닀.

 μ΄ 과정을 λ°˜λ³΅ν•˜λ©΄ 배열이 μ˜€λ¦„μ°¨ 순으둜 μ •λ ¬λœλ‹€.

 

2. μš°μ„ μˆœμœ„ 큐(Priority Queue)

  μš°μ„  μˆœμœ„ νλŠ” 각 μ›μ†Œκ°€ μš°μ„ μˆœμœ„λ₯Ό 가지고 있고, μš°μ„ μˆœμœ„κ°€ κ°€μž₯ 높은 μ›μ†ŒλΆ€ν„° κΊΌλ‚΄ μ‚¬μš©ν•˜λŠ” μžλ£Œκ΅¬μ‘°μ΄λ‹€.

  νž™μ€ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜λŠ”λ° 많이 μ‚¬μš©λœλ‹€.

 

3. λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜(Dijkstra's Algorithm)

  μ•žμ„œ 2-4. Graph representation 의 2-4-2. adjacency listμ—μ„œ μ–ΈκΈ‰λ§Œ ν•˜κ³  λ„˜μ–΄κ°”λŠ”λ°,

(https://parkpakrsu.tistory.com/330)

λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ€ κ·Έλž˜ν”„μ˜ ν•œ λ…Έλ“œμ—μ„œ λ‹€λ₯Έ λ…Έλ“œλ‘œ κ°€λŠ” μ΅œλ‹¨ 경둜λ₯Ό μ°ΎλŠ” μ•Œκ³ λ¦¬μ¦˜μ΄λ‹€.

이 μ•Œκ³ λ¦¬μ¦˜μ€ μš°μ„ μˆœμœ„ 큐λ₯Ό μ‚¬μš©ν•΄ κ΅¬ν˜„λ˜λ©°, 이 λ•Œ νž™μ΄ 주둜 μ‚¬μš©λœλ‹€.

 

4. νžˆν”„ν™”(Heapify)

  νžˆν”„ν™”λŠ” 주어진 데이터λ₯Ό νž™ ꡬ쑰λ₯Ό λ§Œμ‘±ν•˜λ„λ‘ μž¬λ°°μ—΄ ν•˜λŠ” κ³Όμ •.

  주둜 νž™ μ •λ ¬, νž™ 생성 등에 μ‚¬μš©λœλ‹€.

728x90