CS

[자료ꡬ쑰] νž™ (Heap)

moaoh 2024. 11. 8. 02:11

νž™ (Heap) λž€?

  • νŠΉμˆ˜ν•œ νŠΈλ¦¬ 기반 데이터 ꡬ쑰
  • νž™μ€ μš°μ„ μˆœμœ„ 큐λ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•œ μ™„μ „ 이진 트리 ν˜•νƒœμ˜ 자료ꡬ쑰
  • μ΅œλŒ€ νž™ (Max Heap)κ³Ό μ΅œμ†Œ νž™(Min Heap) 총 2κ°€μ§€κ°€ μ‘΄μž¬ν•œλ‹€.

μ΅œλŒ€ νž™ (Max Heap)

  • λΆ€λͺ¨μ˜ λ…Έλ“œκ°€ 항상 μžμ‹μ˜ λ…Έλ“œλ³΄λ‹€ 큰 ꡬ쑰

  1. ν•œμͺ½ λ…Έλ“œλ§Œ 계속 μ§„ν–‰λ˜μ„œλŠ” μ•ˆλœλ‹€.
  2. μ™Όμͺ½κ³Ό 였λ₯Έμͺ½ ν•˜μœ„ νŠΈλ¦¬μ—λ„ 같은 μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Όν•œλ‹€.
  3. λΆ€λͺ¨μ˜ 값보닀 μžμ‹μ˜ 값이 크면 μ•ˆλœλ‹€.

μ΅œμ†Œ νž™(Min Heap)

  • λΆ€λͺ¨μ˜ λ…Έλ“œκ°€ 항상 μžμ‹μ˜ λ…Έλ“œλ³΄λ‹€ μž‘μ€ ꡬ쑰

  1. ν•œμͺ½ λ…Έλ“œλ§Œ 계속 μ§„ν–‰λ˜μ„œλŠ” μ•ˆλœλ‹€.
  2. μ™Όμͺ½κ³Ό 였λ₯Έμͺ½ ν•˜μœ„ νŠΈλ¦¬μ—λ„ 같은 μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Όν•œλ‹€.
  3. λΆ€λͺ¨μ˜ 값보닀 μžμ‹μ˜ 값이 μž‘μœΌλ©΄ μ•ˆλœλ‹€.

μž₯단점

μž₯점

  • μ΅œλŒ€κ°’ λ˜λŠ” μ΅œμ†Œκ°’μ„ λΉ λ₯΄κ²Œ μ°Ύκ³  μ‚½μž…ν•  수 있음.
  • μš°μ„ μˆœμœ„ νλ‚˜ μž‘μ—… μŠ€μΌ€μ€„λ§μ—μ„œ ν™œμš©ν•˜κΈ° μ’‹μŒ.

단점

  • 쀑간 μš”μ†Œμ— μ ‘κ·Όν•˜κΈ° μ–΄λ ΅κ³ , μ‚½μž…/μ‚­μ œ μ‹œ κ· ν˜•μ„ λ§žμΆ”κΈ° μœ„ν•œ μΆ”κ°€ μž‘μ—… ν•„μš”.
  • λ©”λͺ¨λ¦¬ μ‚¬μš©μ΄ λΉ„νš¨μœ¨μ μΌ 수 있음.

κ΅¬ν˜„

#include <iostream>
#include <vector>
#include <algorithm>

class MaxHeap {
private:
	std::vector<int> heap;

	// λΆ€λͺ¨-μžμ‹ 관계λ₯Ό μœ μ§€ν•˜λ©° νž™μ„ μž¬μ •λ ¬ (heapify-down)
	void heapifyDown(int index) {
		int left = 2 * index + 1;
		int right = 2 * index + 2;
		int largest = index;

		// μ™Όμͺ½ μžμ‹μ΄ 더 크면 largestλ₯Ό μ™Όμͺ½ μžμ‹ 인덱슀둜 κ°±μ‹ 
		if (left < heap.size() && heap[left] > heap[largest]) {
			largest = left;
		}

		// 였λ₯Έμͺ½ μžμ‹μ΄ 더 크면 largestλ₯Ό 였λ₯Έμͺ½ μžμ‹ 인덱슀둜 κ°±μ‹ 
		if (right < heap.size() && heap[right] > heap[largest]) {
			largest = right;
		}

		// largestκ°€ λ³€κ²½λ˜μ—ˆμœΌλ©΄ swapν•˜κ³ , μž¬κ·€μ μœΌλ‘œ heapify
		if (largest != index) {
			std::swap(heap[index], heap[largest]);
			heapifyDown(largest);
		}
	}

	// νž™μ„ μœ„λ‘œ μž¬μ •λ ¬ (heapify-up)
	void heapifyUp(int index) {
		while (index > 0 && heap[(index - 1) / 2] < heap[index]) {
			std::swap(heap[index], heap[(index - 1) / 2]);
			index = (index - 1) / 2;
		}
	}

public:
	// μ‚½μž… μ—°μ‚°
	void insert(int value) {
		heap.push_back(value);   // μƒˆλ‘œμš΄ κ°’ μ‚½μž…
		heapifyUp(heap.size() - 1);  // μƒˆλ‘œμš΄ 값이 νž™ 속성을 λ§Œμ‘±ν•˜λ„λ‘ μœ„λ‘œ 올리기
	}

	// 루트 μ‚­μ œ μ—°μ‚° (μ΅œλŒ€κ°’ μ‚­μ œ)
	void removeMax() {
		if (heap.empty()) return;

		// λ£¨νŠΈμ™€ λ§ˆμ§€λ§‰ 값을 κ΅ν™˜
		heap[0] = heap.back();
		heap.pop_back();

		// λ£¨νŠΈλΆ€ν„° μ•„λž˜λ‘œ heapify-down
		heapifyDown(0);
	}

	// 루트 값을 λ°˜ν™˜ (μ΅œλŒ€κ°’)
	int getMax() {
		if (!heap.empty()) {
			return heap[0];
		}
		throw std::out_of_range("Heap is empty");
	}

	// νž™μ„ 좜λ ₯
	void printHeap() {
		for (int val : heap) {
			std::cout << val << " ";
		}
		std::cout << std::endl;
	}

	bool isEmpty() {
		return heap.empty();
	}
};

int main() {
	MaxHeap maxHeap;

	// μ‚½μž…
	maxHeap.insert(10);
	maxHeap.insert(20);
	maxHeap.insert(15);
	maxHeap.insert(30);
	maxHeap.insert(40);

	std::cout << "Max Heap: ";
	maxHeap.printHeap(); // 40 30 15 10 20

	// μ΅œλŒ€κ°’ μ–»κΈ°
	std::cout << "Max Value: " << maxHeap.getMax() << std::endl; // 40

	// μ΅œλŒ€κ°’ 제거
	maxHeap.removeMax();
	std::cout << "Max Heap after removing max: ";
	maxHeap.printHeap(); // 30 20 15 10

	return 0;
}

 

참고자료

https://www.geeksforgeeks.org/introduction-to-heap/