Data Structure
우선순위 큐와 힙
andre99
2024. 9. 11. 15:29
📖우선순위큐와 힙 내용 정리
우선순위 큐와 힙이 같은 개념이라고 오해할 수 있지만 둘은 서로 다른 개념이다.
우선순위 큐와 힙에 대해 알아보기 전, 이를 이해하기 위해 알아둬야할 개념은 다음과 같다.
* 큐 : 먼저 들어온 데이터가 먼저 나가는 형식(First In First Out)의 자료구조이다.
* 완전이진트리 : 왼쪽부터가 오른쪽으로 노드가 채워지는 형식이며, 마지막 레벨을 제외한 모든 레벨이 채워져 있는 형태이다.
- '우선순위 큐'의 특징
- -일반적인 큐와 다르게 우선순위의 개념을 큐에 적용한 자료구조
-들어간 순서에 상관 없이 우선순위를 근거로 dequeue 연산이 진행된다.
-두 요소의 우선 순위가 동일한 경우 대기열에서 해당 요소의 순서에 따라 진행된다. - '힙'의 특징
- -완전 이진 트리
-최대 힙: 모든 노드에 저장된 값은 자식 노드에 저장된 값보다 크거나 같아야 한다. 즉 루트 노드에 저장된 값이 가장 커야 한다.
(부모 key >= 자식 key)
-최소 힙: 모든 노드에 저장된 값은 자식 노드에 저장된 값보다 크거나 같아야 한다. 즉 루트 노드에 저장된 값이 가장 커야 한다.
(부모 key =< 자식 key)
-부모노드와 자식노드 간의 관계
:왼쪽 자식노드 인덱스 = 부모의 인덱스 x 2
:오른쪽 자식노드 인덱스 = 부모의 인덱스 x 2 + 1
:부모노드 인덱스 = 자식노드 인덱스 / 2
📖C++를 이용한 우선순위큐 프로그래밍 방법 정리
우선순위 큐 구현 방법
-배열 기반 구현
enqueue(): 새 데이터를 대기열에 삽입하는 데 사용
dequeue(): 대기열에서 우선 순위가 가장 높은 요소를 제거
peek()/top(): 대기열에서 가장 높은 우선 순위 요소를 제거하지 않고 가져오는 데 사용
-연결리스트 기반 구현
push(): 새 데이터를 큐에 삽입하는 데 사용
pop(): 우선순위가 가장 높은 요소를 대기열에서 제거
peek()/top(): 대기열에서 가장 높은 우선 순위 요소를 제거하지 않고 가져오는 데 사용-힙 기반 구현
insert(p): 우선 순위가 p인 새 요소를 삽입
extractMax(): 최대 우선 순위를 가진 요소를 추출
remove(i): i가 가리키는 요소를 제거
getMax(): 최대 우선 순위를 가진 요소를 반환
changePriority(i, p): i to p가 가리키는 요소의 우선순위를 변경
#include <iostream>
#include <queue>
#include <tuple>
#include <string>
#include <fstream>
using namespace std;
void MaxHeapSorting(int a[], int n) {
priority_queue <int> maxHeap;
for (int i = 0; i < n; ++i)
maxHeap.push(a[i]);
for (int i = 0; i < n; i++) {
a[i] = maxHeap.top();
maxHeap.pop();
}
}
void MinHeapSorting(int a[], int n) {
priority_queue<int, vector<int>, greater<int>>minHeap;
for (int i = 0; i < n; ++i)
minHeap.push(a[i]);
for (int i = 0; i < n; ++i) {
a[i] = minHeap.top();
minHeap.pop();
}
}
💻문제 풀이
- 백준 1966번 - 프린터 큐
#include <iostream>
#include <queue>
#include <fstream>
using namespace std;
int main() { // 메인함수
// 사용될 변수 선언
int num_test_cases;
int N;
int M;
int temp_priority; int tp;
int temp_order;
int cnt;
ifstream fin("Prob_1966.txt"); // txt파일 불러오기
fin >> num_test_cases;
for (int i = 0; i < num_test_cases; ++i) {
fin >> N >> M;
cnt = 0;
queue<pair<int, int>> data;
priority_queue <int> priority_data;
for (int j = 0; j < N; ++j) {
fin >> temp_priority;
data.push({ j,temp_priority });
priority_data.push(temp_priority);
}
while(!data.empty()) {
tp = data.front().first;
temp_order = data.front().second;
data.pop();
if (priority_data.top() == temp_order) {
priority_data.pop();
cnt++;
if (tp == M) {
cout << cnt << endl;
break;
}
}
else {
data.push({ tp, temp_order });
}
}
}
fin.close(); // txt파일 닫기
return 0;
}