본문 바로가기
[C++] Data Structure & Algorithm/A* & Heap

[A* & Heap] Chapter 03. 우선순위 큐 구현

by song.ift 2023. 8. 8.

GitHub : https://github.com/developeSHG/Data_Structure-Algorithm/commit/f9452fae763d2a5c6f359a528f94a64bcebf502c

 

우선순위 큐 구현 · developeSHG/Data_Structure-Algorithm@f9452fa

developeSHG committed Aug 10, 2023

github.com

 

 


 

 

 

우선순위 큐에 push와 pop을 할 때, 시간복잡도는 O(log n)이다. 우선순위 큐는 힙 tree 구조로 이루어져 있기 때문에, 데이터를 삽입하거나 뺐을 때, 비교 연산이 최대 tree의 높이까지 발생하기 때문이다.

#include <iostream>
#include <vector>
#include <list>
#include <stack>
#include <queue>
using namespace std;

template<typename T, typename Container = vector<T>, typename Predicate = less<T>>
class PriorityQueue
{
public:
	void push(const T& data)
	{
		// 우선 힙 구조부터 맞춰준다
		_heap.push_back(data);

		// 도장깨기 시작
		int now = static_cast<int>(_heap.size()) - 1;
		// 루트 노드까지
		while (now > 0)
		{
			// 부모 노드와 비교해서 더 작으면 패배
			int next = (now - 1) / 2;
			if (_predicate(_heap[now], _heap[next]))
				break;

			// 데이터 교체
			::swap(_heap[now], _heap[next]);
			now = next;
		}
	}

	void pop()
	{
		_heap[0] = _heap.back();
		_heap.pop_back();

		int now = 0;

		while (true)
		{
			int left = 2 * now + 1;
			int right = 2 * now + 2;

			// 리프에 도달한 경우
			if (left >= (int)_heap.size())
				break;

			int next = now;

			// 왼쪽과 비교
			if (_predicate(_heap[next], _heap[left]))
				next = left;

			// 첫번째 조건은 right가 없는 경우도 있으니 체크하고, 둘 중 승자를 오른쪽과 비교
			if (right < (int)_heap.size() && _predicate(_heap[next], _heap[right]))
				next = right;

			// 왼쪽/오른쪽 둘 다 현재 값보다 작으면 종료
			if (next == now)
				break;

			::swap(_heap[now], _heap[next]);
			now = next;
		}
	}

	T& top()
	{
		return _heap[0];
	}

	bool empty()
	{
		return _heap.empty();
	}

private:
	Container _heap = {};
	Predicate _predicate = {};
};


int main()
{
	PriorityQueue<int, vector<int>, greater<int>> pq;

	pq.push(100);
	pq.push(300);
	pq.push(200);
	pq.push(500);
	pq.push(400);

	while (pq.empty() == false)
	{
		int value = pq.top();
		pq.pop();

		cout << value << endl;
	}
}

댓글