[Data Structure] Heap

do yeon kim·2022년 10월 2일
0
1번 표현법

앞의 트리에서 트리를 표현하는 방법에는 레벨을 이용한 표현법1
재귀표현법을 이용한 표현법2
노드 클래스를 이용한 표현법3이 있었다.

표현법1을 사용해서 트리를 표현할 경우 장점은 상수시간에 부모노드와 자식노드의 인덱스에 접근할 수 있다는 점이다.

왼쪽자식노드의 인덱스 = 2*현재노드인덱스 + 1
오른쪽자식노드의 인덱스 = 2*현재노드인덱스 + 2
부모노드의 인덱스 = (현재노드인덱스-1) // 2

위의 공식을 이용해서 상수시간에 접근이 가능하다.



Heap

Heap은 자료구조 Binary Tree의 종류 중 하나이다.
이진트리(Binary Tree)는 자식 노드의 수가 최대 2개를 가지는 트리 형태를 의미한다.

이진트리의 모습에 모양성질과 Heap성질을 만족하게 되면 Heap이 된다.

모양성질이란 자식노드 수가 최대 2개 이면서, 위에서 부터 아래로 꽉 채우면서 내려오며, 마지막 레벨에서는 왼쪽부터 차례대로 채워나가는 형태를 의미한다.

Heap 성질이란,
최대 힙의 경우는 부모노드는 자식 노드보다 최소한 크거나 같은 값을 가져야 한다. 이 성질은 루트노드부터 시작해서 아래로 내려가면 모든 노드가 만족해야되는 조건이다.

최소 힙의 경우는 최대 힙과 달리 부모노드가 자식노드보다 작거나 같아야 한다.



make-heap 연산

맨 마지막 노드부터 root로 가면서 해당노드의 자식노드로 내려가면서 힙 성질을 만족하는 위치로 이동시킨다.

n개의 노드로 이루어진 힙의 높이는 h이다.
위의 그림처럼 레벨별로 노드의 갯수는 2^h만큼 노드 수가 늘어나게 된다.
h-1에 해당하는 노드 갯수는 2^n-1이 된다.
맨마지막 h에 해당하는 노드갯수는 전체가 다 채워질수도 있고 1나만 채워질수도 있다.
전체를 합한값은 최소한 n보다 작거나 같게된다.
그러므로 공식을 이용해서 양변을 정리하면 h < log2N 이 된다.



insert 연산

insert연산을 하게 되면 리스트의 맨마지막에 append를 하고서 heap성질이 만족하게 heapify-up()연산을 해준다.

heap을 만드는 방법은 기존의 리스트를 make_heap연산을 해서 만드는 방법도 있고, insert연산을 이용해서 바로바로 heap을 만드는 방법도 존재한다.

make_heap()연산의 경우 O(N) 하며 insert()연산의 경우는 O(NlongN)에 해당한다.



find_max 연산 & delete_max 연산

find_max의 경우 최대힙으로 구현했기 때문에 루트 노드에 해당하는 값을 반환하면 된다.

delete_max의 경우 root노드에 해당하는 값을 제거하고, 맨 끝에 있는 노드를 루트노드로 만들고 다시 heapify-down()연산을 해서 heap성질을 만족하게 하면 된다.



heap 결론

heap자료구조의 경우 search 연산은 없다.
heap은 빠른 삽입, 최대값 찾기를 사용하는 서비스에서 사용하는 자료구조이다.
search를 위한 자료구조에 해당하지 않는다.
데이터를 저장할 때 특정 요소가 어디에 있는지 판단하기 어렵기 때문에 search를 하고자하는 서비스에서 heap을 사용하는 것은 바람직하지 않다.



python heap 라이브러리
import heapq


a = [2,8,6,1,10,15,3,12,11]

heapq.heapify(a) # 최소힙으로 구성된다.
heapq.heappush(a, 4) # insert하면서 heap을 구성
heapq.heappop(a) 
heapq.nlargest(3,a) # 리스트 내에서 크기가 큰 순으로 3개 구한다.
heapq.nsmallest(3,a) # 리스트 내에서 크기가 작은 순으로 3개를 구한다.

0개의 댓글