πŸ“•Week1 day2(22-23)

박쀀희·2023λ…„ 8μ›” 23일

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€

λͺ©λ‘ 보기
5/28
post-thumbnail

νž™(Heap)


πŸ“’νž™μ€ μ΄μ§„νŠΈλ¦¬μ˜ ν•œ μ’…λ₯˜λ‘œ λ£¨νŠΈλ…Έλ“œκ°€ μ–Έμ œλ‚˜ μ΅œλŒ“κ°’λ˜λŠ” μ΅œμ†Ÿκ°’μ„ κ°€μ§‘λ‹ˆλ‹€.(μ΅œλŒ€ νž™, μ΅œμ†Œ νž™ 이라고 ν•œλ‹€.) 그리고 νŠΈλ¦¬λŠ” μ™„μ „μ΄μ§„νŠΈλ¦¬μ—¬μ•Όν•©λ‹ˆλ‹€.

μ΅œλŒ€ νž™


μ—¬κΈ°μ„œλŠ” μ΅œλŒ€ νž™λ§Œ κ΅¬ν˜„ν•΄ λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

μ΅œλŒ€ νž™μ„ κ΅¬ν˜„ν•˜κΈ° 전에 μ„±μ§ˆκ³Ό νŠΉμ§•μ— λŒ€ν•΄ μ–˜κΈ°ν•˜κ³ μž ν•©λ‹ˆλ‹€.

μ΅œλŒ€ νž™μ˜ μ„±μ§ˆ

  1. 루트 λ…Έλ“œκ°€ 항상 μ΅œλŒ“κ°’μ„ κ°€μ§„λ‹€.
  2. μ™„μ „ 이진 νŠΈλ¦¬μ΄λ‹€.
  3. μ΅œλŒ€ νž™ λ‚΄μ˜ μž„μ˜μ˜ λ…Έλ“œλ₯Ό 루트둜 ν•˜λŠ” μ„œλΈŒνŠΈλ¦¬ λ˜ν•œ μ΅œλŒ€ νž™μ΄λ‹€.

μ΅œλŒ€ νž™μ˜ νŠΉμ§•

λΆ€κ°€μ˜ μ œμ•½ 쑰건, 즉 μ™„μ „ 이진 트리 (complete binary tree) μ—¬μ•Ό ν•œλ‹€λŠ” μ œμ•½ λ•Œλ¬Έμ—, n 개의 λ…Έλ“œλ‘œ 이루어진 μ΅œλŒ€ νž™μ˜ 높이 (깊이) λŠ” log(n) + 1 (μ—μ„œ μ†Œμˆ˜ 뢀뢄은 버림) 둜 μ •ν•΄μ§‘λ‹ˆλ‹€. 이 μ„±μ§ˆ λ•Œλ¬Έμ— 데이터 μ›μ†Œμ˜ μ‚½μž…/μ‚­μ œ μ—°μ‚°μ˜ μ‹€ν–‰ μ‹œκ°„μ€ μ–Έμ œλ‚˜ log(n) 에 λΉ„λ‘€ν•©λ‹ˆλ‹€. λ”°λΌμ„œ, μ–΄λ–€ μ΅œλŒ€ νž™μ΄ μ‘΄μž¬ν•  λ•Œ, 이 νž™μœΌλ‘œλΆ€ν„° 반볡적으둜 루트 λ…Έλ“œλ₯Ό μ‚­μ œν•˜λ©΄ (μ„œ 데이터 μ›μ†Œλ“€μ„ κΊΌλ‚΄λ©΄) 루트 λ…Έλ“œμ— λ“€μ–΄ μžˆλŠ” ν‚€κ°€ νž™ λ‚΄μ—μ„œ μ΅œλŒ€μž„μ΄ 보μž₯λ˜μ–΄ μžˆμœΌλ―€λ‘œ 데이터λ₯Ό λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ •λ ¬ν•  수 있고, 이 정렬에 μ†Œμš”λ˜λŠ” μ‹œκ°„ λ˜ν•œ log(n) 에 λΉ„λ‘€ν•©λ‹ˆλ‹€.
νž™μ΄ 항상 μ™„μ „ 이진 νŠΈλ¦¬λΌλŠ” μ„±μ§ˆμ€ 트리의 ν‘œν˜„μ— μžˆμ–΄μ„œλ„ 이점을 μ œκ³΅ν•©λ‹ˆλ‹€. (λ™μ˜μƒ κ°•μ˜μ—μ„œ μ†Œκ°œλ ) κ·œμΉ™μ— 따라 λ…Έλ“œλ“€μ— 번호λ₯Ό λ§€κΈ°λ©΄, 이 번호 μˆœμ„œλ‘œ 이루어진 μ„ ν˜• 배열에 트리λ₯Ό ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, μ™„μ „ 이진 νŠΈλ¦¬μ΄λ―€λ‘œ λ…Έλ“œμ˜ 좔가와 μ‚­μ œλŠ” λ°°μ—΄μ˜ 맨 λ§ˆμ§€λ§‰ μ›μ†Œμ—μ„œλ§Œ μΌμ–΄λ‚©λ‹ˆλ‹€.

μ΅œλŒ€ νž™ κ΅¬ν˜„

μ΅œλŒ€ νž™ κ΅¬ν˜„μ— μžˆμ–΄μ„œ 배열을 μ΄μš©ν•œ μ΄μ§„νŠΈλ¦¬λ‘œ κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€.

class MaxHeap:
    def __init__(self):
        self.data = [None]

    def insert(self, item):
        # 흰트 - pythonμ—μ„œ 두 λ³€μˆ˜μ˜ κ°’ λ°”κΎΈκΈ°
        # a = 3, b = 5
        # a, b  = b, a
        self.data.append(item)

        index = len(self.data) -1

        while index != 1:
            numOfParentNode = index//2
            print(numOfParentNode)

            if self.data[numOfParentNode] < self.data[index]:
                self.data[numOfParentNode], self.data[index] = self.data[index], self.data[numOfParentNode]
                index = numOfParentNode
            else:
                break

    def remove(self):
        if len(self.data) > 1:
            self.data[1], self.data[-1] = self.data[-1], self.data[1] #μ΅œμƒλ‹¨ λ…Έλ“œμ™€ λ°”κΏˆ
            data = self.data.pop(-1) # λ§λ‹¨μœΌλ‘œ κ°€μžˆλŠ” Max 값을 제거
            self.maxHeapify(1) # λ‹€μ‹œ MaxHeap λͺ¨μ–‘μœΌλ‘œ 정리

        else:
            data = None
        return data

    def maxHeapify(self, i):
        left = i*2
        right = i*2+1
        smallest = i
        if left < len(self.data) and self.data[left] > self.data[smallest]:
            # 쑰건이 λ§Œμ‘±ν•˜λŠ” 경우, smallestλŠ” μ™Όμͺ½ μžμ‹μ˜ 인덱슀λ₯Ό κ°€μ§‘λ‹ˆλ‹€.
            smallest = left
        # 였λ₯Έμͺ½ μžμ‹μ΄ μ‘΄μž¬ν•˜λŠ”μ§€, 그리고 였λ₯Έμͺ½ μžμ‹μ˜ (ν‚€) 값이 λΆ€λͺ¨λ…Έλ“œλ³΄λ‹€ 더 큰지λ₯Ό νŒλ‹¨ν•©λ‹ˆλ‹€.
        if right < len(self.data) and self.data[right] > self.data[smallest]:
            # 쑰건이 λ§Œμ‘±ν•˜λŠ” 경우, smallestλŠ” 였λ₯Έμͺ½ μžμ‹μ˜ 인덱슀λ₯Ό κ°€μ§‘λ‹ˆλ‹€.
            smallest = right
        if smallest!= i:
            # ν˜„μž¬ λ…Έλ“œ (인덱슀 i)와 μ΅œλŒ“κ°’ λ…Έλ“œ (μ™Όμͺ½ μ•„λ‹ˆλ©΄ 였λ₯Έμͺ½ μžμ‹)λ₯Ό κ΅μ²΄ν•©λ‹ˆλ‹€.
            self.data[smallest], self.data[i] = self.data[i], self.data[smallest]
            # μž¬κ·€μ  ν˜ΈμΆœμ„ μ΄μš©ν•˜μ—¬ μ΅œλŒ€ νž™μ˜ μ„±μ§ˆμ„ λ§Œμ‘±ν•  λ•ŒκΉŒμ§€ 트리λ₯Ό μ •λ¦¬ν•©λ‹ˆλ‹€.
            self.maxHeapify(smallest)

profile
κ²Œμ„λ €λ˜ ν”„λ‘œκ·Έλž˜λ° 곡뢀

0개의 λŒ“κΈ€