์•Œ๊ณ ๋ฆฌ์ฆ˜

[Data Structure] ํž™ (Heap)์˜ ๊ตฌํ˜„ - ํž™๊ณผ ๋ฐฐ์—ด

jjingle 2024. 1. 30. 10:51

ํž™๊ณผ ๋ฐฐ์—ด

  • ์ผ๋ฐ˜์ ์œผ๋กœ ํž™ ๊ตฌํ˜„ ์‹œ, ๋ฐฐ์—ด ์ž๋ฃŒ๊ตฌ์กฐ ํ™œ์šฉ
  • ๋ฐฐ์—ด์€ ์ธ๋ฑ์Šค 0 ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์ง€๋งŒ, ํž™ ๊ตฌํ˜„์˜ ํŽธ์˜๋ฅผ ์œ„ํ•ด root ๋…ธ๋“œ ์ธ๋ฑ์Šค ๋ฒˆํ˜ธ๋ฅผ 1๋กœ ์ง€์ •
    • ๋ถ€๋ชจ ๋…ธ๋“œ ์ธ๋ฑ์Šค(parent node's index) = ์ž์‹ ๋…ธ๋“œ ์ธ๋ฑ์Šค(child node's index) //2
    • ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ ์ธ๋ฑ์Šค(left child node's index) = ๋ถ€๋ชจ ๋…ธ๋“œ ์ธ๋ฑ์Šค(parent node's index) * 2
    • ์˜ค๋ฅธ์ชฝ ์ž์‹  ๋…ธ๋“œ ์ธ๋ฑ์Šค(right child node's index) = ๋ถ€๋ชจ ๋…ธ๋“œ ์ธ๋ฑ์Šค(parent node's index) * 2 + 1

Heap ๊ณผ ์ธ๋ฑ์Šค ๋ฒˆํ˜ธ

ํž™๊ณผ ๋ฐ์ดํ„ฐ ์‚ฝ์ž…(Max Heap)

class Heap:
    def __init__(self, data):
            self.heap_array = list()
            self.heap_array.append(None)
            self.heap_array.append(data)


heap = Heap(1)
heap.heap_array  #[None, 1]
  • insert()
def insert(self, data):
    if len(self.heap_array) == 0:
        self.heap_array.append(None)
        self.heap_array.append(data)
        return True

    self.heap_array.append(data)
    return True
  • insert() ๋ณ€ํ˜• : ์‚ฝ์ž…ํ•œ ๋…ธ๋“œ๊ฐ€ ๋ถ€๋ชจ ๋…ธ๋“œ๊ฐ’๋ณด๋‹ค ํด ๊ฒฝ์šฐ, ๋ถ€๋ชจ ๋…ธ๋“œ์™€ ์‚ฝ์ž…๋…ธ๋“œ ์œ„์น˜ ๋ณ€๊ฒฝ
def move_up(self, inserted_idx):
    if inserted_idx <= 1:
        return False

    parent_idx = inserted_idx // 2
    if self.heap_array[inserted_idx] > self.heap_array[parent_idx]:
        return True
    else:
        return False

def insert(self, data):
    if len(self.heap_array) == 0:
        self.heap_array.append(None)
        self.heap_array.append(data)
        return True

    self.heap_array.append(data)

    inserted_idx = len(self.heap_array) - 1

    while self.move_up(inserted_idx):
        parent_idx = inserted_idx // 2
        self.heap_array[inserted_idx], self.heap_array[parent_idx] = self.heap_array[parent_idx], self.heap_array[inserted_idx]
        inserted_idx = parent_idx

    return True

 

ํž™์˜ ๋ฐ์ดํ„ฐ ์‚ญ์ œ(Max Heap)

  • ๋ณดํ†ต ์‚ญ์ œ๋Š” ์ตœ์ƒ๋‹จ ๋…ธ๋“œ(root node)๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ 
  • (cf. ํž™์˜ ์šฉ๋„๋Š” ์ตœ๋Œ€๊ฐ’ ๋˜๋Š” ์ตœ์†Œ๊ฐ’์„ root node์— ๋†“์•„์„œ, ๋น ๋ฅด๊ฒŒ ๊บผ๋‚ด์“ฐ๋„๋ก ํ•˜๋Š” ๊ฒƒ)
class Heap:
    def __init__(self, data):
        self.heap_array = list()
        self.heap_array.append(None)
        self.heap_array.append(data)

    def pop(self):
        if len(self.heap_array) <= 1:
            return None

        returned_data = self.heap_array[1]
        return returned_data

 

ํž™(Heap) ์‹œ๊ฐ„ ๋ณต์žก๋„

  • depth(ํŠธ๋ฆฌ์˜ ๋†’์ด)๋ฅผ h๋ผ๊ณ  ํ‘œ๊ธฐ
  • n๊ฐœ์˜ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ง€๋Š” heap์— ๋ฐ์ดํ„ฐ ์‚ฝ์ž… ๋˜๋Š” ์‚ญ์ œ ์‹œ, ์ตœ์•…์˜ ๊ฒฝ์šฐ root ๋…ธ๋“œ์—์„œ leaf ๋…ธ๋“œ๊นŒ์ง€ ๋น„๊ตํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” O(logn)
    • ์ฐธ๊ณ  : ๋น…์˜ค ํ‘œ๊ธฐ๋ฒ•์—์„œ logn ์—์„œ log์˜ ๋ฐ‘์€ 2
    • ํ•œ๋ฒˆ ์‹คํ–‰ ์‹œ, 50%์˜ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ๋Š” ๋ช…๋ น์„ ์ œ๊ฑฐํ•œ๋‹ค๋Š” ์˜๋ฏธ => 50%์˜ ์‹คํ–‰์‹œ๊ฐ„์„ ๋‹จ์ถ•์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค!