힙(Heap)의 노드가 n개라면, 트리의 높이(Depth)인 에 수렴한다.
즉, 시간 복잡도는 이다.
부모 노드 인덱스 = 자식 노드 인덱스 // 2
왼쪽 자식 노드 인덱스 = 부모 노드 인덱스 * 2
오른쪽 자식 노드 인덱스 = 부모 노드 인덱스 * 2 + 1
class Heap:
def __init__(self, data):
self.heap_array = list()
# 1번 인덱스가 루트 노드
self.heap_array.append(None)
self.heap_array.append(data)
# 추가한 노드의 값이 부모 노드의 값보다 큰지 작은지 확인하는 함수
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 insertData(self, data):
if len(self.heap_array) == 0:
self.heap_array.append(None)
self.heap_array.append(data)
return True
else:
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
heap = Heap(15)
heap.insertData(10)
heap.insertData(8)
heap.insertData(5)
heap.insertData(4)
heap.insertData(20)
print(heap.heap_array)
# 출력
[None, 20, 10, 15, 5, 4, 8]
class Heap:
def __init__(self, data):
self.heap_array = list()
# 1번 인덱스가 루트 노드
self.heap_array.append(None)
self.heap_array.append(data)
# 노드의 값이 자식 노드의 값보다 큰지 작은지 확인하는 함수
def move_down(self, popped_idx):
left_node_idx = popped_idx * 2
right_node_idx = popped_idx * 2 + 1
# 1. 왼쪽, 오른쪽 자식 노드가 없을 경우
if left_node_idx >= len(self.heap_array):
return False
# 2. 왼쪽 자식 노드만 있을 경우
elif right_node_idx >= len(self.heap_array):
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
return True
else:
return False
# 3. 왼쪽, 오른쪽 자식 노드가 모두 있을 경우
else:
if self.heap_array[left_node_idx] > self.heap_array[right_node_idx]:
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
return True
else:
return False
else:
if self.heap_array[popped_idx] < self.heap_array[right_node_idx]:
return True
else:
return False
# 힙의 데이터를 삭제하는 함수
def popData(self):
if len(self.heap_array) <= 1:
return None
returned_data = self.heap_array[1]
popped_idx = 1
# 마지막에 추가한 노드를 루트 노드로 옮긴다.
self.heap_array[popped_idx] = self.heap_array.pop()
while self.move_down(popped_idx):
left_node_idx = popped_idx * 2
right_node_idx = popped_idx * 2 + 1
# 왼쪽 노드만 있을 경우
if right_node_idx >= len(self.heap_array):
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
self.heap_array[popped_idx], self.heap_array[left_node_idx] = self.heap_array[left_node_idx], self.heap_array[popped_idx]
popped_idx = left_node_idx
# 왼쪽, 오른쪽 노드 모두 있을 경우
else:
if self.heap_array[left_node_idx] > self.heap_array[right_node_idx]:
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
self.heap_array[popped_idx], self.heap_array[left_node_idx] = self.heap_array[left_node_idx], self.heap_array[popped_idx]
popped_idx = left_node_idx
else:
if self.heap_array[popped_idx] < self.heap_array[right_node_idx]:
self.heap_array[popped_idx], self.heap_array[right_node_idx] = self.heap_array[right_node_idx], self.heap_array[popped_idx]
popped_idx = right_node_idx
return returned_data
heap = Heap(15)
heap.insertData(10)
heap.insertData(8)
heap.insertData(5)
heap.insertData(4)
heap.insertData(20)
print(heap.heap_array)
heap.popData()
print(heap.heap_array)
# 출력
[None, 20, 10, 15, 5, 4, 8]
[None, 15, 10, 8, 5, 4]
class Heap:
def __init__(self, data):
self.heap_array = list()
# 1번 인덱스가 루트 노드
self.heap_array.append(None)
self.heap_array.append(data)
# 추가한 노드의 값이 부모 노드의 값보다 큰지 작은지 확인하는 함수
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 move_down(self, popped_idx):
left_node_idx = popped_idx * 2
right_node_idx = popped_idx * 2 + 1
# 1. 왼쪽, 오른쪽 자식 노드가 없을 경우
if left_node_idx >= len(self.heap_array):
return False
# 2. 왼쪽 자식 노드만 있을 경우
elif right_node_idx >= len(self.heap_array):
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
return True
else:
return False
# 3. 왼쪽, 오른쪽 자식 노드가 모두 있을 경우
else:
if self.heap_array[left_node_idx] > self.heap_array[right_node_idx]:
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
return True
else:
return False
else:
if self.heap_array[popped_idx] < self.heap_array[right_node_idx]:
return True
else:
return False
# 힙에 데이터를 추가하는 함수
def insertData(self, data):
if len(self.heap_array) == 0:
self.heap_array.append(None)
self.heap_array.append(data)
return True
else:
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
# 힙의 데이터를 삭제하는 함수
def popData(self):
if len(self.heap_array) <= 1:
return None
returned_data = self.heap_array[1]
popped_idx = 1
# 마지막에 추가한 노드를 루트 노드로 옮긴다.
self.heap_array[popped_idx] = self.heap_array.pop()
while self.move_down(popped_idx):
left_node_idx = popped_idx * 2
right_node_idx = popped_idx * 2 + 1
# 왼쪽 노드만 있을 경우
if right_node_idx >= len(self.heap_array):
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
self.heap_array[popped_idx], self.heap_array[left_node_idx] = self.heap_array[left_node_idx], self.heap_array[popped_idx]
popped_idx = left_node_idx
# 왼쪽, 오른쪽 노드 모두 있을 경우
else:
if self.heap_array[left_node_idx] > self.heap_array[right_node_idx]:
if self.heap_array[popped_idx] < self.heap_array[left_node_idx]:
self.heap_array[popped_idx], self.heap_array[left_node_idx] = self.heap_array[left_node_idx], self.heap_array[popped_idx]
popped_idx = left_node_idx
else:
if self.heap_array[popped_idx] < self.heap_array[right_node_idx]:
self.heap_array[popped_idx], self.heap_array[right_node_idx] = self.heap_array[right_node_idx], self.heap_array[popped_idx]
popped_idx = right_node_idx
return returned_data