당신의 데이터 더미 구조의 완전한 지침!
#22일차
더미의 정의
Heap: 완전한 두 갈래 나무 () (노드마다 최대 두 개의 자 노드가 있고 모든 잎은 왼쪽으로 기울어야 한다) 로 뿌리 노드와 자 노드를 비교하고 그에 상응하여 배열한다.
전체 두 갈래 트리 예
불완전한 두 갈래 나무 예
더미의 유형
1. 최대 더미
모든 노드의 키는 부모 노드보다 작거나 같다
arr[parent] >= arr[i]
가장 많은 예
2.최소더미
각 노드의 키가 상위 노드보다 크거나 같음
arr[parent] <= arr[i]
최소 무더기의 예
무더기의 응용
쌓인 공간과 시간의 복잡성
쌓인 공간의 복잡도는 O (n) 이다
삽입(밀어넣기)
삭제(pop)
훔쳐보다
O(대수 n)
O(대수 n)
O(1)
더미 진열 실현
max heap을 예로 들겠습니다.
각 노드의 인덱스는 괄호() 사이에 있습니다.
15(0)
/ \
(1) 9 13 (2)
/ \ /
(3)5 (4)7 (5)11
arr = [15, 9, 13, 5, 7, 11]
다음과 같은 방법으로 구현할 수 있습니다.arr[0] = root
arr[(i - 1) // 2]
arr[2 * i + 1]
arr[2 * i + 2]
class MinHeap:
def __init__(self):
self.heap = []
self.heap_size = 0
def getParentNodeIndex(self, i: int) -> int:
return (i-1)//2
def getLeftChildNodeIndex(self, i: int) -> int:
return 2*i+1
def getRightChildNodeIndex(self, i: int) -> int:
return 2*i+2
def hasParent(self, i: int) -> bool:
# cheking if a node has a parent
return self.getParentNodeIndex(i) < len(self.heap)
def hasLeftChild(self, i: int) -> bool:
# cheking if a node has a left child
return self.getLeftChildNodeIndex(i) < len(self.heap)
def hasRightChild(self, i: int) -> bool:
# cheking if a node has a right child
return self.getRightChildNodeIndex(i) < len(self.heap)
def getMinValue(self) -> int:
"""
time complexity => O(1)
"""
return self.heap[0]
def printAll(self):
print(self.heap)
스택에 삽입(밀어넣기)
1. 삽입 방법
1. 설명 삽입
더 잘 이해하기 위해서 우리는 예를 들자.
저희가 이 작은 더미에 1을 넣고 싶어요.
3 (0)
/ \
(1) 5 10 (2)
/
9 (3)
[3, 5, 10, 9]
3 (0)
/ \
(1) 5 10 (2)
/ \
(3)9 (4)1
heap_size += 1
arr = [3, 5, 10, 9, 1]
3 (0)
/ \
(1) 1 10 (2)
/ \
(3)9 (4)5
arr = [3, 5, 10, 9, 1]
newElementIndex = len(arr) - 1 # 4
# the index of the parent of the new element
ParentIndex = (newElementIndex - 1) // 2 # (4-1)//2 = 1
# 1 < 5
if arr[newElementIdx] < arr[ParentIdx]:
# swap(1, 5)
arr[newElementIdx], arr[ParentIdx] = arr[ParentIdx], arr[newElementIdx]
스토리지는 다음과 같습니다.arr = [3, 1, 10, 9, 5]
1 (0)
/ \
(1) 3 10 (2)
/ \
(3)9 (4)5
우리는 1과 3에 대해 같은 과정을 수행할 것이다. 예를 들어 (1과 5)이기 때문에 수조는arr = [1, 3, 10, 9, 5]
3.python에 삽입된 실현
python에서 bubble up 또는 Heapify 함수의 실현
def bubbleUp(self, i: int):
parentIndex = self.getParentNodeIndex(i)
if parentIndex < 0:
parentIndex = 0
# Loops until it reaches a leaf node
while(i > 0 and self.heap[i] < self.heap[self.getParentNodeIndex(i)]):
# Swap the elements
self.heap[i], self.heap[self.getParentNodeIndex(i)] = self.heap[self.getParentNodeIndex(i)], self.heap[i]
i = self.getParentNodeIndex(i)
python에 함수 삽입
def insert(self, value: int):
self.heap_size += 1
# insert the element at the end
self.heap.append(value)
# bubble up the new element
self.bubbleUp(len(self.heap) - 1)
더미에서 삭제
1. 삭제 방법
쌓아 올리는 표준 삭제 작업은 루트를 삭제하는 것입니다. 이것은 max Heap의 최대 값이자 in Heap의 최소 값입니다.
1. 설명 삭제
더 잘 이해하기 위해서 우리는 예를 들자.
저희가 이 작은 더미 중 3개를 삭제하고 싶어요.
3 (0)
/ \
(1) 5 10 (2)
/
9 (3)
[3, 5, 10, 9]
9 (0)
/ \
(1) 5 10 (2)
/
(3)3
arr = [9, 5, 10, 3]
9 (0)
/ \
(1) 5 10 (2)
arr = [9, 5, 10, 3]
heap_size -= 1
arr.pop()
그래서 어레이는 arr = [9, 5, 10]
5 (0)
/ \
(1) 9 10 (2)
arr = [5, 9, 10]
3.python에서 삭제된 실현
python의 거품 구현
def bubbleDown(self):
# the index of the root => 0
i = 0
while True:
smallest = None
leftChildIndex = self.getLeftChildNodeIndex(i)
rightChildIndex = self.getRightChildNodeIndex(i)
# if the node has not any child
if (not self.hasLeftChild(i) and not self.hasRightChild(i)):
break
# if the node has only a left child
elif (not self.hasRightChild(i)):
# the smallest variable will be the index of the left child
smallest = leftChildIndex
# if the node has only a right child
elif (not self.hasLeftChild(i)):
# the smallest variable will be the index of the right child
smallest = rightChildIndex
# if the node has 2 children
else:
# the smallest variable will be the smallest value of the 2 children
smallest = rightChildIndex if self.heap[rightChildIndex] < self.heap[leftChildIndex] else leftChildIndex
# if the node's value is greater than its one of children
if (self.heap[i] > self.heap[smallest]):
# swap the node with its child
self.heap[i], self.heap[smallest] = self.heap[smallest], self.heap[i]
# the i variable will be the index of the smallest value of the two children
i = smallest
# if the node's value is smaller than its one of children
else:
break
return
python에서 실행 삭제
def delete(self):
# if the size the heap is one or the heap is empty(size = 0)
if self.heap_size <= 1:
self.heap = []
return
# replace last element with the root
self.heap[self.heap_size - 1], self.heap[0] = self.heap[0], self.heap[self.heap_size - 1]
# decrease the size of heap
self.heap_size -= 1
# delete last element
self.heap.pop()
self.bubbleDown()
python의 무더기 구현 (최종 코드)
class MinHeap:
def __init__(self):
self.heap = []
self.heap_size = 0
def getParentNodeIndex(self, i: int) -> int:
return (i-1)//2
def getLeftChildNodeIndex(self, i: int) -> int:
return 2*i+1
def getRightChildNodeIndex(self, i: int) -> int:
return 2*i+2
def hasParent(self, i: int) -> bool:
# cheking if a node has a parent
return self.getParentNodeIndex(i) < len(self.heap)
def hasLeftChild(self, i: int) -> bool:
# cheking if a node has a left child
return self.getLeftChildNodeIndex(i) < len(self.heap)
def hasRightChild(self, i: int) -> bool:
# cheking if a node has a right child
return self.getRightChildNodeIndex(i) < len(self.heap)
def getMinValue(self) -> int:
"""
time complexity => O(1)
"""
return self.heap[0]
def insert(self, value: int):
self.heap_size += 1
# insert the element at the end
self.heap.append(value)
# bubble up the new element
self.bubbleUp(len(self.heap) - 1)
def bubbleUp(self, i: int):
parentIndex = self.getParentNodeIndex(i)
if parentIndex < 0:
parentIndex = 0
# Loops until it reaches a leaf node
while(i > 0 and self.heap[i] < self.heap[self.getParentNodeIndex(i)]):
# Swap the elements
self.heap[i], self.heap[self.getParentNodeIndex(i)] = self.heap[self.getParentNodeIndex(i)], self.heap[i]
i = self.getParentNodeIndex(i)
def delete(self):
# if the size the heap is one or the heap is empty(size = 0)
if self.heap_size <= 1:
self.heap = []
return
# replace last element with the root
self.heap[self.heap_size - 1], self.heap[0] = self.heap[0], self.heap[self.heap_size - 1]
# decrease the size of heap
self.heap_size -= 1
# delete last element
self.heap.pop()
self.bubbleDown()
def bubbleDown(self):
# the index of the root => 0
i = 0
while True:
smallest = None
leftChildIndex = self.getLeftChildNodeIndex(i)
rightChildIndex = self.getRightChildNodeIndex(i)
# if the node has not any child
if (not self.hasLeftChild(i) and not self.hasRightChild(i)):
break
# if the node has only a left child
elif (not self.hasRightChild(i)):
# the smallest variable will be the index of the left child
smallest = leftChildIndex
# if the node has only a right child
elif (not self.hasLeftChild(i)):
# the smallest variable will be the index of the right child
smallest = rightChildIndex
# if the node has 2 children
else:
# the smallest variable will be the smallest value of the 2 children
smallest = rightChildIndex if self.heap[rightChildIndex] < self.heap[leftChildIndex] else leftChildIndex
# if the node's value is greater than its one of children
if (self.heap[i] > self.heap[smallest]):
# swap the node with its child
self.heap[i], self.heap[smallest] = self.heap[smallest], self.heap[i]
# the i variable will be the index of the smallest value of the two children
i = smallest
# if the node's value is smaller than its one of children
else:
break
return
def printAll(self):
print(self.heap)
my_heap = MinHeap()
my_heap.insert(5)
my_heap.insert(10)
my_heap.insert(1)
my_heap.insert(2)
my_heap.insert(3)
my_heap.insert(4)
# 1
# / \
# 2 4
# / \ /
# 10 3 5
my_heap.printAll()
my_heap.delete()
my_heap.printAll()
# 2
# / \
# 3 4
# / \
# 10 5
print(my_heap.heap_size) # 5
print(my_heap.getMinValue()) # 2
참고 자료와 유용한 자원
해피 코딩:)
#22일차
Reference
이 문제에 관하여(당신의 데이터 더미 구조의 완전한 지침!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/ayabouchiha/your-complete-guide-to-heap-data-structure-20nl텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)