๐ intro
๐ Priority Queue์ ์ฐ๊ฒฐ์ง์ด ์ค๋ช ํ ์ ์๋ Binary Heap data structure์ ๋ํด ์์ธํ ์์๋ณด์. ์์ ํ์ตํ Priority Queue๋ ์ผ์ข ์ Abstract Data Structure(ADT)๋ก, binary heap์ ์ถ์ํํ ๊ฐ๋ ์ด๋ผ ๋ณผ ์ ์๋ค. ์ฆ, ์ค์ priority queue๋ binary heap์ด๋ผ ์๊ฐํ๋ฉด ๋๋ค. priority queue์ ์ฐ์ ์์๊ฐ ์ต๋ ๋จผ์ , ๋๋ ์ต์ ๋จผ์ ๋ผ๋ฉด binary heap์ผ๋ก tree structure๋ฅผ ๋ง๋ค์ด tree structure์์ ์ฐ์ ์์์ ๋ง๊ฒ ๊บผ๋ด์ค๋ค. ์ต๋ ๋จผ์ ๋ผ๋ฉด max-heap, ์ต์ ๋จผ์ ๋ผ๋ฉด min-heap์ด๋ผ ๋ถ๋ฅธ๋ค. (์ฌ๊ธฐ์ priority queue๋ ๋ฌด์กฐ๊ฑด binary heap์ ์ด์ฉํด์ ๊ตฌํ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ์๋๋ค. ์ฃผ๋ก binary heap์ด ๋ง์ด ์ฐ์ผ ๋ฟ ๋ค๋ฅธ heap๋ ์ฐ์ธ๋ค.)
๐ ์์ ์ธ๊ธํ Binary Heap์ Heap Data Structure์ ์ผ์ข ์ผ๋ก, binary heap์ธ leftis, binomial, fibonacci, pairing, brodal, rank-pairing, strict fibonacci, 2-3 heap๊ณผ ๊ฐ์ ๋ค์ํ heap ์กด์ฌ. ์๋์ ๊ฐ์ด ์ด๋ฒ ํฌ์คํ ์์ ๋ฐฐ์ธ Binary Heap์ ์๋ ํ์ ๊ฐ์ด deletion / insertion ๋ชจ๋ ์๊ฐ ๋ณต์ก๋ O(logN)์ด๋ค. O(N)๋ณด๋ค ์์ผ๋ฏ๋ก ํจ์จ์ ์ด๋ค๋ผ๋ ๋ถ๋ถ์์ ๋ํ ์๋ฃ๊ตฌ์กฐ๋ก ๋ง์ด ์ฌ์ฉ.
๐ tree structure ํํ์ binary heap์ด๋ผ๊ณ ํ์๋๋ฐ, tree์ค complete binary tree structure์์ ๋ฐ์จ ๊ฒ์ binary heap์ด๋ผ ์๊ฐํ๋ฉด ๋๋ค. Binary Heap์ ๋ง์กฑํ๊ธฐ ์ํด์๋ Complete Binary Tree Structure๋ผ๋ shape์ ๋ง์กฑํด์ผ ํ๊ณ (shape property ์ถฉ์กฑ), Heap ์ฑ์ง์ ๋ง์กฑํด์ผ ํ๋ค(heap property ์ถฉ์กฑ)
๐ โ Shape Property → Complete Binary Tree
๐ Complete Binary Tree(CBT; ์์ ์ด์ง ํธ๋ฆฌ)๋, root ๋ ธ๋๋ถํฐ ์์ํ์ฌ ์ผ์ชฝ ์์ ๋ ธ๋, ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋ ์์๋๋ก ๋ฐ์ดํฐ๊ฐ ์ฐจ๋ก๋๋ก ์ฝ์ ๋๋ tree๋ฅผ ๋ปํ๋ค. 'all levels of the tree, except possibly the last one (deepest) are fully filled, and, if the last level of the tree is not complete, the nodes of that level are filled from left to right.' ๋งจ ๋ง์ง๋ง level์ ์ ์ธํ๊ณ ๋ชจ๋ level์ด ์ฑ์์ ธ ์๊ณ , ๋ง์ง๋ง level์ ๊ฒฝ์ฐ ์ผ์ชฝ๋ถํฐ ์์ ๋ ธ๋๊ฐ ์ต๋ํ ์ฑ์์ง tree๋ผ ๋ณด๋ฉด ๋๋ค. ์๋ ์ผ์ชฝ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด Complete Binary Tree๋ฅผ ์ฑ์ธ ์ ์๋ค. ๊ทธ๋ ๋ค๋ฉด CBT ์ ์์ ์ํด ์๋ ์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์์ CBT๋ 1, 2, 5, 6์์ ์ ์ ์๋ค.
๐ โก Heap Property → Max-Heap & Min-Heap
๐ ์ด์ โ ์ ํตํด Shape Property ์กฐ๊ฑด์ ๋ํด ์์๋ณด์๊ณ , ๋๋ฒ์งธ ์กฐ๊ฑด Heap Property์ ๋ํด์ ์์๋ณด์. ๋ property๋ฅผ ๋ชจ๋ ๋ง์กฑํด์ผ Binary Heap์ด๋ผ ํ ์ ์๋ค. 'Heap property: the key stored in each node is either greater than or equal to (≥) or less than or equal to (≤) the keys in the node's children, according to some total order.'
๐ max-heap: parent key๊ฐ child keys๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ heap / min-heap: parent key๊ฐ child keys๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ heap. ์ฆ max-heap์ root node๊ฐ ๊ฐ์ฅ ํฐ ๊ฐ์ ๊ฐ์ง๋ฉฐ(child node ๊ฐ ๋ณด๋ค ๋ชจ๋ ํฌ๊ฑฐ๋ ๊ฐ์์ผ ํ๋ค), ๊ฐ์ฅ ๊ฐ์ด ํฐ ๋ฐ์ดํฐ๊ฐ ์ฐ์ ์ ์ผ๋ก ์ ๊ฑฐ๋๋ค. ์ฆ deletion ์งํ ์ root node๋ถํฐ ์ ๊ฑฐ๋๋ค. min-heap์ ๊ทธ ๋ฐ๋. deletion ์ฐจ๋ก๋๋ก ์งํํ๋ฉด์ extract๋ ์์๋ค ์ฐจ๋ก๋๋ก ๋ฐฐ์น๋ง ํด๋ ์๋์ผ๋ก ์ ๋ ฌ ์ํ. max-heap์ ๊ฒฝ์ฐ ์ต๋๊ฐ์ผ๋ก extraction ์งํํ๋ฏ๋ก ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ / min-heap์ ๊ฒฝ์ฐ ์ค๋ฆ์ฐจ์ ์ ๋ ฌ ๊ฒฐ๊ณผ.
๐ max-heap๊ณผ min-heap์ ๋ฐ๋ผ์ priority queue implementation ์ element๋ฅผ insertion / ๋๋ ๊ฐ์ฅ ์๊ฑฐ๋ ํฐ element๋ฅผ min-heap๊ณผ max-heap์์ deletionํ๋ ๋ operation์์ ํจ์จ์ ์ด๊ฒ ๋ง์ด ์ฐ์ธ๋ค.
๐ ํด๋น ์ ๋ ฌ์ heapsort sorting algorithm(in-place algorithm)์ผ๋ก, tree structure ๋ด์์ ์๋ก node๋ผ๋ฆฌ ์๋์ ์ผ๋ก ์์น๋ฅผ ๋ฐ๊พธ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ฏ๋ก in-place ์๊ณ ๋ฆฌ์ฆ์ด๋ค. (sorting ๊ณผ์ ์ ์๋ ๋ด์ฉ ์์ธํ ์ฐธ์กฐ) / ์๋ ๊ทธ๋ฆผ ์ผ์ชฝ max-heap / ์ค๋ฅธ์ชฝ min-heap
๐ binary heap implementations
๐ heap ๊ตฌํ์ linked list์ array ๋ ๊ตฌ์กฐ๋ก ๊ตฌํ์ด ๊ฐ๋ฅํ๋ฐ, linked list๋ ๋ง์ ๋ฉ๋ชจ๋ฆฌ ์ฐจ์ง,์ฃผ๋ก array๋ก ๊ตฌํ๋๋ค. array์ index๋ฅผ ์ด์ฉํด heap binary tree์ ์๋ ๊ณผ์ ์ ์์๋ณด์. binary heap์ array๋ก ๊ตฌํํ๊ธฐ์ ์์์ child & parent node index๋ฅผ ๋จผ์ ์์๋ณด์
โ child & parent's node index
๐ ์์ node์ index๊ฐ i๋ผ๋ฉด(index 0๋ถํฐ ์์ ์) ํ์ left node์ index๋ 2i+1, ํ์ right node์ index๋ 2i+2์ด๋ค. ๋ฐ๋๋ก ์์ node์ index๊ฐ x๋ผ๋ฉด paret node์ index๋ floor((x-1)/2)
๐ ์ค์ heapsort๋ ์ 1์ฐจ์ array ๋ด์ ์์๋ฅผ swapํ๋ ๊ณผ์ ์ผ๋ก 1์ฐจ์ array ํ์ ๋ด sortingํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์งํ๋๋ค(in-place)
โก building a heap
๐ ๊ทธ๋ ๋ค๋ฉด ์ฃผ์ด์ง array๋ฅผ binary heap ํํ(max heap ๊ฐ์ )๋ก ์ ์ฅํ๋ ๊ณผ์ ์ ํ ๋จ๊ณ์ฉ ์์ธํ ์ดํด๋ณด์
โ ์ฃผ์ด์ง array์ ์ค๊ฐ ์์๋ถํฐ(arr[(len(arr)-2)//2]: index 0 ๊ธฐ์ค) ๋งจ ์ ์์๊น์ง for๋ฌธ ๋ฐ๋ณต๋ฌธ์ผ๋ก ์๋ swapํ๋ ๊ณผ์ (heapify())์ ๋๋ฆฐ๋ค.
Q. ์ฃผ์ด์ง array์ ์ ์ฒด๋ฅผ ๋๋ฆฌ์ง ์๊ณ ์ค๊ฐ ์์๋ถํฐ ๋๋ฆฌ๋ ์ด์ ?
A. child node๊ฐ ์๋ parent node๋ heapify ๊ณผ์ (์๋๋ก ๋ป์ด๋๊ฐ๋ฉฐ swap ํ๋ ๊ณผ์ )์ด ํ์ ์๊ธฐ ๋๋ฌธ. child node๊ฐ ์กด์ฌํ๋ parent node๋ถํฐ ๋๋ ค์ผ ํ๋ฏ๋ก ํด๋น parent node์ ๊ฐ์๋, ์ ์ฒด index๋ฅผ N์ด๋ผ ํ๋ฉด index N//2์ธ node์์๋ถํฐ ์์ํ๋ค.
(์ฐธ๊ณ : child node๊ฐ ์กด์ฌํ๋ node๋ฅผ non-leaf node, child node๊ฐ ์กด์ฌํ์ง ์๋ ๋ ธ๋๋ฅผ leaf node. ๋ฐ๋ผ์ non-leaf node๋ถํฐ iteration ์งํ)
Q. ์ฃผ์ด์ง array์ ์ค๊ฐ ์์๋ถํฐ ์ฒซ๋ฒ์งธ ์์๊น์ง ๊ฑฐ๊พธ๋ก ๋๋ฆฌ๋ ์ด์ ?
A. subarray ์์ฒด๋ฅผ heap์ผ๋ก ๋ฐ๊พธ๊ธฐ ์ํด์๋ ํด๋น subarray ๋ด์ ๋ชจ๋ subarray๋ heap์ ๋ง์กฑ์์ผ์ผ ํ๋ค. ํ์ง๋ง ์ฒซ๋ฒ์งธ ์์๋ถํฐ ๋๋ฆฌ๋ ์๊ฐ, ์ฒซ๋ฒ์งธ ์์๋ฅผ ํฌํจํ ์ ์ฒด array ๋ด์ ๋ชจ๋ subarray๊ฐ ์ด๋ฏธ heap์์ ๋ณด์ฅํ ๋ฆฌ ์์ผ๋ฏ๋ก ๊ฑฐ๊พธ๋ก ๋๋ ค์ ์๋์์ ์๋ก ์ฌ๋ผ๊ฐ๋ฉฐ heap์ ๋ง์กฑ์ํค๋ ๊ณผ์ ์ด ์ฌ๋ฐ๋ฅด๋ค.
โก swapํ๋ heapify() ๊ณผ์
(1) largest index ๊ตฌํ๊ธฐ
: max heap์ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํ์ ๋, parent node๋ฅผ A, ๋ child node๊ฐ ์๋ค๊ณ ํ๋ฉด ์ผ์ชฝ๋ถํฐ B, C๋ผ๊ณ ํ์. max heap์ด๋ฏ๋ก A์ value >= max(B์ value, C์ value)๋ฅผ ๋ฌด์กฐ๊ฑด ๋ง์กฑํด์ผ ํ๋ค. ์ด ๋ ํด๋น ๋ถ๋ฑ์์ ๋ง์กฑ์ํค์ง ์๋, ์ฆ B, C์ค A์ value๋ณด๋ค ๋ ํฐ node๊ฐ ์กด์ฌํ๋ค๋ฉด largest๋ผ๋ index๋ฅผ B ๋๋ C์ index๋ก ๋ฐ๊พผ๋ค. (๋ง์ฝ B์ C ๋ ๋ค A์ value๋ณด๋ค value๊ฐ์ด ํฌ๋ค๋ฉด C์ value๋ฅผ largest๋ก ๋ฐฐ์ )
(2) ๊ตฌํ largest index๊ณผ ๋ณธ๋ parent_idx์ ๋ค๋ฅด๋ค๋ฉด?
: largest != parent_idx๋ผ๋ฉด parent node์ largest๋ฅผ ๊ฐ๋ฆฌํค๋ node์์ value swap ์งํ. ํด๋น swap์ดํ largest๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ณธ๋ child node๋ฅผ parent node๋ก ์ ํด ์ฌ๊ท์ ์ผ๋ก ์ (1)๊ณผ ํ์ฌ (2)์ ๊ณผ์ ์ฌ๊ท์ ์ผ๋ก ์คํ
(3) ์ฌ๊ท์ ์ผ๋ก ์๋ subtree๊น์ง ์คํํจ์ผ๋ก์จ subtree๋ฅผ max-heap์ผ๋ก ์์ฑ
๐ ex) array [33, 35, 42, 10, 7, 8, 14, 19, 48]์ด ์ฃผ์ด์ก๋ค๊ณ ํ์. heapify()์ swap ๊ณผ์ ๊ทธ๋ฆผ ์ผ๋ถ ์ฐธ์กฐ.
→ ์๋ ์ผ์ชฝ ๊ทธ๋ฆผ์์ last non-leaf node (index 3) 10๋ถํฐ reverse iteration ์งํ. (์ฆ index 3 - 2 - 1 - 0์์ผ๋ก swap heapify() ์คํ)
→ ์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์ index 1์ผ ๋์ heapify(). index 1์ผ๋ heapify()๋ฅผ ์งํํ ๊ฑด๋ฐ, ์ด๋ ๊ณง index 2๋ฅผ root node๋ก ๊ฐ์ง๋ sub-tree์ index3์ root node๋ก ๊ฐ์ง๋ sub-tree๊ฐ ์ด๋ฏธ ์์ฑ๋ ์ํ.
→ ๊ทธ ๋ค์ ์ค ์ผ์ชฝ ๊ทธ๋ฆผ์ index 1์ผ ๋์ heapify() ๊ทธ๋ฆผ. parent_idx์ largest๊ฐ ๋ค๋ฅด๋ฏ๋ก swap ์งํ
→ ๊ทธ ๋ค์ ์ค ์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ์ index 0์ผ ๋์ heapify() ๊ทธ๋ฆผ. parent_idx์ largest๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ๊ฐ 2๋ฒ ์์ผ๋ฏ๋ก swap 2๋ฒ ์งํ
∴ ์ต์ข ๊ฒฐ๊ณผ heapify()์ ๊ฒฐ๊ณผ๋ก [48, 35, 42, 33, 7, 8, 14, 19, 10] max heap ์์ฑ
def heapify(arr, n, parent_idx):
largest = parent_idx
left = parent_idx*2 + 1
right = parent_idx*2 + 2
if left < n and arr[left] > arr[largest]:
largest = left
if right < n and arr[right] > arr[largest]:
largest = right
if largest != parent_idx: #if changed
arr[largest], arr[parent_idx] = arr[parent_idx], arr[largest] #swap
heapify(arr, n, largest) #if swapped, continue with the lower part
arr = [33, 35, 42, 10, 7, 8, 14, 19, 48]
for i in range((len(arr)-2)//2,-1,-1): #heapify
heapify(arr, len(arr), i)
print(arr) #[48, 35, 42, 33, 7, 8, 14, 19, 10]
โข Time Complexity: heapfiy() O(N) (๊ฐ node๋ณ heapify()๋ฅผ ์ฌ๋ฌ ๋ฒ ์ํ)
(1) ์ด n๊ฐ์ node๊ฐ ์๋ค๊ณ ๊ฐ์ . ๋ฐ๋ฅ๋ถํฐ h=0, ๊ทธ ๋ค์ ์ธต h=1๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์งํ๋๋ค๊ณ ๊ฐ์ ํ๋ฉด, h๋ผ๋ ์ธต์ ์กด์ฌํ๋ ์ต๋ node ๊ฐ์๋ n/(2^(h+1))
(2) last non-leaf node๋ถํฐ root-node๊น์ง(leaf node๋ child node์์ผ๋ฏ๋ก heapify() ์งํ ํ์ x) ๊ฐ๊ฐ heapify()๊ฐ ์งํ๋๋ค. ์ด ๋, heapify()์์ swap์ ์ํ comparison ํ์๋ ์ต๋ ์์ node์ height๋ผ ํ ์ ์๋ค. ๋ฐ๋ผ์ height h์์์ ์๊ฐ๋ณต์ก๋๋ O(h) x ⌈(n/2^(h+1))⌉
(O(h)๋ ์์ node์ height๋ก ์ผ์ ์์ c*h๋ก ํํ ๊ฐ๋ฅ)
(3) ๊ฐ ๋ชจ๋ ์ธต์ ์๊ฐ๋ณต์ก๋๋ฅผ ๊ตฌํ๋ฉด, n๊ฐ์ node์์ ์ธต์ ๊ฐ์๋ logn์ด๋ฏ๋ก ์๋์ ๊ฐ์ด ํํํ ์ ์๋ค. logn์ ∞๋ก ๋ฐ๊พธ๋ฉด harmonic progression์ ์ํด์ sigma ๊ฐ์ 2๊ฐ ๋๋ค.
(4) c*n์ด๋ฏ๋ก heapify()์ ์๊ฐ๋ณต์ก๋๋ O(n)
โข deletion in a heap → heapsort
๐์ด๋ฏธ ์์ฑ๋ binary heap์์ ํ ์์๋ฅผ deleteํ ๋ค๋ ๊ฒ์, ๊ฐ์ฅ ์์์ root node๋ฅผ ๋นผ ์จ๋ค๋ ๋ป์ด๊ณ , max-heap์ผ ๊ฒฝ์ฐ ์์์ ์ต๋๊ฐ, min-heap์ผ ๊ฒฝ์ฐ ์์์ ์ต์๊ฐ์ ๊ฐ์ ธ์ค๊ฒ ๋๋ค. root- node๋ฅผ ๋นผ์ค๊ณ ๋จ์ ์๋ฆฌ์๋, bottom-most right-most element๋ฅผ ๋นผ์จ๋ค. (array๊ตฌ์กฐ์ index๊ฐ ๊ฐ์ฅ ํฐ, ๋งจ ์ค๋ฅธ์ชฝ์ ์์). ์ด๋ฅผ root node์ ์ฌ๋ ค๋๋๋ค. bottom-most right-most element๋ฅผ ๋นผ์ค๋ ์ด์ ๋ array์ ๋งจ ์ค๋ฅธ์ชฝ ์์ ๋นผ๋ pop() ์ฐ์ฐ์ด O(1) ํจ์จ์ ์ด๊ธฐ ๋๋ฌธ.
๐ ex) ์๋์ max heap์์ root node์ด์ ์ ์ฒด ์์์ ์ต๋๊ฐ 42๋ฅผ ๋นผ๊ณ , bottom-most right-most element 10์ ๋งจ ์์ ์ฌ๋ ค ๋๋๋ค. ์ด ๋, ํญ์ max-heap ๊ตฌ์กฐ๋ฅผ ์ ์งํด์ผ ํ๋ฏ๋ก, ์ โก ๊ณผ์ ์์ ์ ์ํ heapify() ๊ณผ์ ๋๋ก swap ์งํ.
(์๋ก ๋ฐ๋ root-node์ child-node๋ฅผ ๋น๊ต. swap์ด ์งํ๋๋ฉด, ์ดํ ์๋ ๋ถ๋ถ๊น์ง ๋์ ๊ด๊ณ๊ฐ max-heap ๊ตฌ์กฐ์ ๋ง์ง ์์ผ๋ฉด ๊ณ์ํด์ swap ์งํ)
๐ update๋ max-heap์ array ํํ๋ก ํํํ๋ฉด [35, 33, 14, 19, 7, 8, 10]์ด ๋๋ค. ์ด์ ๊ฐ์ด ๊ณ์ํด์ root-node deletion์ ์งํํ๋ฉด ์ ์ผ ํฐ ์๋ถํฐ ์ฐจ๋ก๋๋ก delete๋๋ค. ๋ฐ๋ผ์, delete๋ ์์๋ฅผ ์ฐจ๋ก๋๋ก ๋ชจ์ผ๋ฉด, sort๋ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค. ์ด sorting์ heapsort(increasing-order)๋ผ๊ณ ๋ถ๋ฅธ๋ค.
def max_heap(arr, n, parent_idx):
largest = parent_idx
left = parent_idx*2 + 1
right = parent_idx*2 + 2
if left < n and arr[left] > arr[largest]:
largest = left
if right < n and arr[right] > arr[largest]:
largest = right
if largest != parent_idx: #if changed
arr[largest], arr[parent_idx] = arr[parent_idx], arr[largest] #swap
max_heap(arr, n, largest) #if swapped, continue with the lower part
def heapsort(arr):
n = len(arr)
for i in range((n-1)//2,-1,-1): #(1) building a max heap O(N)
max_heap(arr, n, i)
for i in range(n-1,0,-1): #heapsort (until last single element remained)
arr[i], arr[0] = arr[0], arr[i] #(2) swap with the last and the first(max) element O(1)
max_heap(arr,i,0) #(3) after swapped, heapify (start with the first element) O(logN)
arr = [33, 35, 42, 10, 7, 8, 14, 19, 48]
heapsort(arr)
print(arr) #[7, 8, 10, 14, 19, 33, 35, 42, 48]
โ ์ฃผ์ด์ง array๋ฅผ max heap์ผ๋ก ๋ง๋ค๊ธฐ: heapify (O(N))
โก max heap์์ root node ๋นผ๊ณ root node ์๋ฆฌ์ bottom-most right-most element ๋ฃ๊ธฐ (O(1))
โข bottom-most right-most element ์๋ฆฌ ์ ์ธํ ๋๋จธ์ง tree heapify (O(logN))
(*max_heap ๋๋ฒ์งธ ์ธ์ i๊ฐ node ์ต๋๊ฐ ๋ฒํธ์ด๋ฏ๋ก sub-tree ๋ฒ์ ์ ํ ์ ์ ์์)
โฃ ์ โก์ โข๊ณผ์ ๋ฐ๋ณต. ๋ฐ๋ณตํ ๊ฒฐ๊ณผ heapsort๋ก ์ค๋ฆ์ฐจ์ ๋๋ ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ ์์ฑ. ์๊ฐ ๋ณต์ก๋๋ O(N + N*(O(1) + O(logN))) = O(N + N + Nlog(N)) = O(2N + NlogN) = O(NlogN))
ex) ์๋ ์์์์ โ ๊ณผ์ ์ผ๋ก ์์ฑ๋ max heap์์ max_value๋ฅผ bottom-most right-most element ์๋ฆฌ์ swap. ๊ทธ ๊ฒฐ๊ณผ 10์ root node์ ๋ฃ๋๋ค(O(1)) ๊ทธ ๋ค์, root node 10๋ถํฐ heapify ์งํ(O(logn)) (์๋ ์ค๋ฅธ์ชฝ ๊ทธ๋ฆผ). ๊ทธ ๊ฒฐ๊ณผ ๊ทธ ๋ค์ max value 42๋ฅผ 19์ swap ์งํ. ๋จ์ node์์ ๊ณ์ ๊ฐ์ ๊ณผ์ ๋ฐ๋ณต.
โฃ insertion in a heap
๐ ์ด๋ฏธ ์์ฑ๋ heap์์ ๋งจ ๋ง์ง๋ง์ ์๋ก์ด ์์๋ฅผ insertionํ ์ ์๋ค. ์ด ๋, max-heap์ ์ฑ์ง์ ์ ์งํ๊ธฐ ์ํด ๋ถ๋ชจ ๋ ธ๋ ์์์ ๊ณ์ ๋น๊ตํ๋ฉฐ ์ต๋ root node ์์๊น์ง swap ์งํ. (ํ๋จ ๊ทธ๋ฆผ ์ฐธ์กฐ) / ๋งจ ๋ง์ง๋ง์ insertion ํ๋ ์ด์ ๋, sub-tree max-heap property๋ฅผ ๊ณ์ ๋ง์กฑ์ํค๊ธฐ ์ํจ. (ํ๋จ ๊ทธ๋ฆผ 51์ ๋ฃ์์ ๊ฒฝ์ฐ ์์ node ๊น์ง 3๋ฒ swap)
๐ ์ฝ๋๋ก ๊ตฌํ ํ์ ๋(index 0 ์์ ๊ธฐ์ค), child node์ index๊ฐ i๋ผ๋ฉด, parent node์ index๋ i//2์ด๋ค. index๋ก parent์ child ๋น๊ตํ๋ฉด์ ์์๊น์ง swap ์งํ.
def insert_key(arr,key):
arr.append(key)
size=len(arr)
i=size
while(i>=1 and arr[i/2] < arr[i]):
arr[i],arr[i/2] = arr[i/2],arr[i] #swap
i = (i/2)
print(arr)
๐ ๋ฐ๋ผ์ 1 node insertion ๊ณผ์ ์ O(logn) (swap)
โค extract max(or min) from heap
๐ ์ง๊ธ max-heap์ ๋ค๋ฃจ๊ณ ์์ผ๋ฏ๋ก, heap์ ์์ ์ค ์ต๋๊ฐ์ ๊ฐ์ฅ ์์ ๋ ธ๋์ ์๋ ๊ฐ์ด๋ค. ๋ฐ๋ผ์ ๋งจ ์์ ๋ ธ๋๋ฅผ ๋นผ๊ณ , ๊ทธ ์๋ฆฌ์ ๊ฐ์ฅ ๋์ ์๋ ์์๋ฅผ ๊ฐ๋ค ์ค๋ค. (ํ๋จ ๊ทธ๋ฆผ ์ฐธ์กฐ). ๋ค๋ง max heap ์ฑ์ง์ ๊ณ์ ์ ์งํด์ผ ํ๋ฏ๋ก ๊ฐ์ฅ ๋์ ์๋ ์์๊ฐ root- node๊ฐ ๋ ์ดํ heapify() ์ ๊ณผ์ ๋์ผํ๊ฒ ์งํ. ์๊ฐ๋ณต์ก๋๋ O(1) + O(logn)์ผ๋ก O(logn)
def delete_max(arr):
size=len(arr)
if size < 1:
print('Error')
max_root = arr[0]
arr[0] = arr[size]
size=size-1
A=max_heapify(arr[:size],1)
return max_root
๐Binary Heap Time Complexity
'Computer Science > Data Structures' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
โก๏ธ Linked List (0) | 2024.09.26 |
---|---|
๐ Monotonic Stack (0) | 2024.09.23 |
๐ฅชArray & Linked List Intro (2) | 2024.01.08 |
๐ณ Binary Tree ๐ณ (1) | 2023.12.19 |
๐ Map (0) | 2023.08.03 |
๋๊ธ