Skip to content

Latest commit

ย 

History

History
169 lines (130 loc) ยท 3.63 KB

PrQue.md

File metadata and controls

169 lines (130 loc) ยท 3.63 KB

์šฐ์„ ์ˆœ์œ„ ํ (Priority Queue)

ํž™(Heap)์„ ํ†ตํ•ด ๊ตฌํ˜„๋˜๋ฉฐ FIFO(First In First Out)์ธ Queue์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋จผ์ € ๋‚˜๊ฐ€๋Š” ํ˜•ํƒœ์˜ ์ž๋ฃŒ๊ตฌ์กฐ์ด๋‹ค.


ํž™(Heap)

์™„์ „์ด์ง„ํŠธ๋ฆฌ๋กœ ์ตœ๋Œ“๊ฐ’, ์ตœ์†Ÿ๊ฐ’ ํƒ์ƒ‰์ด ๋น ๋ฅด๋‹ค

  • ์ด์ง„ํƒ์ƒ‰ํŠธ๋ฆฌ(BST)์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์ค‘๋ณต๋œ ๊ฐ’์ด ํ—ˆ์šฉ๋œ๋‹ค
  • ์ตœ๋Œ€ ํž™(Max Heap): ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ํ‚ค ๊ฐ’์ด ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ํฌ๊ฑฐ๊ฐ€ ๊ฐ™์€ ์™„์ „์ด์ง„ํŠธ๋ฆฌ
  • ์ตœ์†Œ ํž™(Min Heap): ๋ถ€๋ชจ ๋…ธ๋“œ์˜ ํ‚ค ๊ฐ’์ด ์ž์‹ ๋…ธ๋“œ๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ์™„์ „์ด์ง„ํŠธ๋ฆฌ

> ํž™์€ ๋™์ ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„๋˜๋ฉฐ ์™„์ „์ด์ง„ํŠธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ฆผ๊ณผ ๊ฐ™์€ idx๋ฅผ ๊ฐ–๋Š”๋‹ค

ํž™์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐฐ์—ด์„ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•œ๋‹ค.

  • idx 0์€ root ๋…ธ๋“œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค
  • i๋ฒˆ์งธ ์™ผ์ชฝ ์ž์‹ ๋…ธ๋“œ์˜ idx: (i * 2) + 1
  • i๋ฒˆ์งธ ์˜ค๋ฅธ์ชฝ ์ž์‹ ๋…ธ๋“œ์˜ idx: (i * 2) + 2
  • i๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ์˜ root ๋…ธ๋“œ idx: (i / 2)
  • ์›์†Œ ์‚ฝ์ž…/์‚ญ์ œ: O(logn)
  • ์›์†Œ ํƒ์ƒ‰: O(1)

์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•œ ์ดํ›„์— Heap์„ ๋งŒ์กฑ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ ์ •๋ ฌํ•˜๋Š” ๊ณผ์ •์ด ์กด์žฌํ•œ๋‹ค


๋ฐ์ดํ„ฐ ์‚ฝ์ž…ํ›„ ์ •๋ ฌ

// ํž™์— ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
_heap.push_back(data);

// ์‚ฝ์ž…๋œ ๋ฐ์ดํ„ฐ ์ถ”์ถœ
int now = static_cast<int>(_heap.size()) - 1;
	// ๋ฃจํŠธ ๋…ธ๋“œ๊นŒ์ง€
	while (now > 0)
	{
	    // ๋ถ€๋ชจ ๋…ธ๋“œ์™€ ๋น„๊ตํ•ด์„œ ๋” ์ž‘์œผ๋ฉด ํŒจ๋ฐฐ
		int next = (now - 1) / 2;
		if (max(_heap[now], _heap[next]))
			break;

		// ๋ฐ์ดํ„ฐ ๊ต์ฒด
		::swap(_heap[now], _heap[next]);
		now = next;
		}
  • ํž™ ๊ตฌ์กฐ์— ๋งž๊ฒŒ ๋ฐฐ์—ด์˜ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค
  • ์ดํ›„ ๋ถ€๋ชจ๋…ธ๋“œ์™€ ๋น„๊ตํ•ด์„œ ๋ถ€๋ชจ๋…ธ๋“œ๋ณด๋‹ค ํฌ๋‹ค๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ„์†ํ•ด์„œ ๊ต์ฒดํ•ด๋‚˜๊ฐ„๋‹ค.

์šฐ์„ ์ˆœ์œ„ ํ

์ผ๋ฐ˜์ ์œผ๋กœ ์™„์ „์ด์ง„ํŠธ๋ฆฌ์˜ ์ผ์ข…์ธ ํž™์œผ๋กœ ๊ตฌํ˜„๋˜๋ฉฐ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„ ์›์†Œ๋“ค๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๋‹ค.



์šฐ์„ ์ˆœ์œ„ ํ์˜ ๊ตฌํ˜„

#include <iostream>
#include <vector>
#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;

			// ๋‘˜ ์ค‘ ์Šน์ž๋ฅผ ์˜ค๋ฅธ์ชฝ๊ณผ ๋น„๊ต
			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;
	}
}