들어오는 순서가 priority가 될 수도 있고, 다른 것에 기반하여 priority를 매길 수 있음
→ 들어오는 순서가 중요하지 않고, priority가 중요
이렇게 보면 queue는 들어오는 순서가 priority인 것
stack과 FIFO queue를 priority queue로 implement할 수 있음
| Data structure | Elements to be removed |
|---|---|
| Stack | Most recent data |
| Queue | First incoming data |
| Priority queue | Highest priority data |
A collection of elements with a priority of n element types
priority queue은 두 카테고리로 나뉨
minimum을 takeout
maximum을 takeout



Time complexity of each data structures
Data structure Insertion operation Deletion operation Unordered array O(1) O(n) Unordered linked list O(1) O(n) Ordered array O(n) O(1) Ordered linked list O(n) O(1) Heap O(logn) O(logn) → priority queue에서는 heap을 사용할 것임
Complete binary tree satisfying the following conditions
key(parent node) >= key(child node)
key(parent node) <= key(child node)
max heap과 min heap은 binary search tree와는 약간 다름

- parent node of node i: i/2
- left child node of node i: 2i
- right child node of node i: 2i+1
인덱스는 0이 아닌 1에서 시작함
Insertion in min heap 또한 유사한 procedure
if the key k is less than or equal to the parent node, the comparison terminates
worst case에 heap의 높이만큼 비교하기 때문!
insert_max_heap(A, key)
heap_size = heap_size + 1;
i = heap_size;
A[i] = key; //우선 current heap의 last index에 key 놓기
while(i!=1 && A[i]>A[PARENT(i)]) do
swap A[i] and A[PARENT];
i = PARENT(i);
heap의 특성에 따라 다른 child와는 비교하지 않아도 됨
children are always smaller or equal to parent node
→ new node가 parent보다 크면 당연하게 other child보다 큼
void insert_max_heap(HeapType *h, element item){
int i;
i = ++(h->heap_size);
//heap은 인덱스가 1부터 시작하기 때문에 heap size를 키운 뒤 i가 heap size 값을 가지도록 함
while((i!=1) && (item.key > h->heap[i/2].key)){
h->heap[i] = h->heap[i/2];
i/=2;
//new node보다 부모 노드가 작은 경우 new node의 위치에 부모 노드가 가도록 함
//효율성을 위해 일일이 new node까지 이동시키는 일은 하지 않음(no exchange operation)
}
h->heap[i] = item; //맨 마지막에 new node 위치 지정
}
deleting the node with the largest key value
If the key k is larger than or equal to the child nodes, the comparison terminates
* complete binary tree의 조건만족을 위해 last location(not the smallest one)의 노드를 root에 놓는 것 *
worst case에 heap의 높이만큼 비교하기 때문!
delete_max_heap(A)
item = A[1];
A[1] = A[heap_size];
heap_size -= 1;
i = 2;
while(i<=heap_size) do
//두 자식 중 크기가 더 큰 것 확인
if (i < heap_size && A[i+1] > A[i+1])
then largest = i+1;
else largest = i;
if(A[PARENT(largest)] > A[largest])
then break;
swap A[PARENT(largest)] and A[largest];
i = CHILD(largest);
return item;
element delete_max_heap(HeapType *h){
int parent, child;
element item, temp;
item = h->heap[1];
temp = h->heap[(h->heap_size)--];
parent = 1;
child = 2;
while(child <= h->heap_size){
if((child < h->heap_size) && (h->heap[child].key)<(h->heap[child+1].key))
child++;
if(temp.key >= h->heap[child].key) break;
h->heap[parent] = h->heap[child];
parent = child;
child *= 2;
}
h->heapp-[parent] = temp;
return item;
}

time complexity 도출 과정
the sorting algorithm using the heap
1. Insert n elements to be sorted in the max heap
2. Delete a root from the max heap and save it in and array n times
Step 1: O(n_log₂_n) + Step 2: O(n_log₂_n)
Step 1에서 build-max-heap()을 사용해도 heap sort의 time complexity는 계속 O(n_log₂_n)
Heap sort is useful, when you need a few of the largest values, not sorting the entire data
Ex) 1000개의 elements 중 10개의 data만 가져오고 싶을 때
Step 1에서 build-max-heap()을 사용하면 효율적으로 할 수 있음
void heap_sort(element a[], int n){
int i;
HeapType h;
init(&h);
for(i=0; i<n; i++){
insert_max_heap(&h, a[i]);
}
for(i=(n-1); i>=0; i--){
//ascending order로 data를 저장할 것이기 때문에 n-1부터 1 순서로 저장
a[i] = delete_max_heap(&h);
}
}
designs a model of physical system, runs the model using computers, and then analyzes the execution results
while(clock < duration){
clock++;
.....
}
while(t < test_time){
t += random(max_arr_interval+1);
//generate an event below
}
1,2는 base on the time, 3은 base on the event
Example of discrete event simulation
Guests visit the ice cream shop. If there is no seat available, then, they will just leave. Our goal is to predict how many chairs can be placed to maximize profits.
typedef struct{
int id; //guest group ID
int type; //event type(arrived or leaving..)
int key; //time when the event occurred(ex. arrival time)
int number; //number of guests for the event
}element; //element == event
ARRIVAL event
ORDER event
LEAVE event
Note that min heap is used in this simulation, since the event that occurs first must be processed
#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "time.h"
#define ARRIVAL 1
#define ORDER 2
#define LEAVE 3
#define MAX_ELEMENT 1000
typedef struct element {
int id; //guest group ID
int type; //event type(arrived or leaving..)
int key; //time when the event occurred(ex. arrival time)
int number; //number of guests for the event
}element;
typedef struct HeapType{
element heap[MAX_ELEMENT];
int heap_size;
}HeapType;
int free_seats = 10;
int test_time = 10;
double profit_per_icecream = 0.35;
double profit = 0.0;
int groups = 0; //total number of guest groups
//Random variables of ARRIVAL event
int max_arr_interval = 6; //손님은 0~6분 사이에 도착함
int max_num_of_guests = 4 //손님은 1~4명 가능
//Random variables of ORDER event
int max_time_to_order = 4 // 주문에 걸리는 시간은 1~4분
int max_num_icecream = 3 //손님은 3스쿱까지 주문 가능
//Random variables of LEAVE event
int max_time_to_stay = 10; //먹고 떠날 때까지 걸리는 시간 1~10분
//Basic functions of heap
void init(HeapType *h){
h->heap_size = 0;
}
int is_empty(HeapType *h){
if(h->heap_size == 0)
return true;
else
return false;
}
void insert_min_heap(HeapType *h, element item){
int i;
i = ++(h->heap_size);
while((i!=1) && (item.key < h->heap[i/2].key)){
h->heap[i] = h->heap[i/2];
i /= 2;
}
h->heap[i] = item;
}
element delete_min_heap(HeapType *h){
int parent, child;
element item, temp;
item = h->heap[1];
temp = h->heap[(h->heap_size)--];
parent = 1;
child = 2;
while(child <= h->heap_size){
if((child < h->heap_size) && (h->heap[child].key) > (h->heap[child+1].key))
child++;
if(temp.key <= h->heap[child].key) break;
h->heap[parent] = h->heap[child];
parent = child;
child *= 2;
}
h->heap[parent] = temp;
return item;
}
//Integer random number generation function between 0 and n-1
int random(int n){
return rand()%n;
}
//If seats are available, reduce the number of remaining chairs by the number of guests
int is_seat_available(element e){
printf("group %d of %d guests arrive\n", e.id, e.number);
if(free_seats >= e.number){
free_seats -= e.number;
return true;
}
else {
printf("group %d of %d quests leave because there is no seat\n", e.id, e.number);
return false;
}
}
//when you receive an order, increase the variable representing the net profit
void order(element e, int scoops){
printf("in group %d, %d ice creams orders\n", e.id, scoops);
profit += profit_per_icecream * ((double)scoops);
}
void leave(element e){
printf("group %d of %d guests leaves\n", e.id, e.number);
free_seats += e.number;
}
// MAIN SUB FUNCTION
void process_event(HeapType *heap, element e){
int i=0;
element new_event;
printf("\nCurrent Time = %d\n", e.key);
switch(e.type){
case ARRIVAL:
if(is_seat_available(e)){
//create an ORDER event
new_event.id = e.id;
new_event.type = ORDER;
new_event.key = e.key+1+random(max_time_to_order);
new_event.number = e.number;
insert_min_heap(heap, new_event);
}
break;
case ORDER:
//주문 받고
for(i=0; i<e.number; i++){
order(e, 1+random(max_num_icecream));
}
//LEAVE event 만들기
new_event.id = e.id;
new_event.type = LEAVE;
new_event.key = e.key+1+random(max_time_to_stay);
new_event.number = e.number;
insert_min_heap(heap, new_event);
break;
case LEAVE:
//increase the number of free seats when guests leave
leave(e);
break;
}
}
int main(){
time_t t1;
/*initialize random number generator*/
srand((unsigned) time (&t1));
element event;
HeapType heap;
int t=0;
init(&heap);
while(t<test_time){
t += random(max_arr_interval+1);
event.id = groups++;
event.type = ARRIVAL;
event.key = t;
event.number = 1+random(max_num_of_guests);
insert_min_heap(&heap, event);
}
while(!is_empty(&heap)){
event = delete_min_heap(&heap);
process_event(&heap, event);
}
printf("\nTotal net profit = %f.\n\n", profit);
}
코드가 길어서 복잡해 보이는데 보면 생각보다 간단함!
데이터를 압축할 때 사용하는 거라고 보면 됨
is for data compression(e.g., JPEG)

prefix가 겹치면 해석이 불가능해지므로 겹치지 않도록 해야 함
Ex) a: 0, b: 01일 때, a와 b 해석 불가능
Optimal codeword is represented by a full binary tree, in which every non-leaf node has two children


#define MAX_ELEMENT 1000
typedef struct TreeNode{
int weight;
struct TreeNode *left_child;
struct TreeNode *right_child;
}TreeNode;
typedef struct {
TreeNode *ptree;
int key;
}element;
typedef struct{
element heap[MAX_ELEMENT];
int heap_size;
}HeapType;
//initialization
void init(HeapType *h){
h->heap_size = 0;
}
int is_empty(HeapType *h){
if(h->heap_size==0)
return true;
else
return false;
}
void insert_min_heap(HeapType *h, element item){
int i;
i = ++(h->heap_size);
while((i!=1) && (item.key < h->heap[i/2].key)){
h->heap[i] = h->heap[i/2];
i /= 2;
}
h->heap[i] = item;
}
element delete_min_heap(HeapType *h){
int parent, child;
element item, temp;
item = h->heap[1];
temp = h->heap[(h->heap_size)--];
parent = 1;
child = 2;
while(child <= h->heap_size){
if((child < h->heap_size) && (h->heap[child].key) > (h->heap[child+1].key))
child++;
if(temp.key <= h->heap[child].key) break;
h->heap[parent] = h->heap[child];
parent = child;
child *= 2;
}
h->heap[parent] = temp;
return item;
}
//Node generation in binary tree
TreeNode *make_tree(TreeNode *left, TreeNode *right){
TreeNode *node = (TreeNode*)malloc(sizeof(TreeNode));
if(node == NULL){
fprintf(stderr, "memory allocation error\n");
exit(1);
}
node->left_child = left;
node->right_child = right;
return node;
}
//binary tree removal
void destroy_tree(TreeNode *root){
if(root==NULL) return;
destroy_tree(root->left_child);
destroy_tree(root->right_child);
free(root);
}
//Huffman code generation
void huffman_tree(int freq[], int n){
int i;
TreeNode *node, *x;
HeapType heap;
element e, e1, e2;
init(&heap);
for(i=0; i<n; i++){
node = make_tree(NULL, NULL);
e.key = node->weight = freq[i];
e.ptree = node;
insert_min_heap(&heap, e);
}
for(i=1; i<n; i++){
//delete two nodes with minimum values
e1 = delete_min_heap(&heap);
e2 = delete_min_heap(&heap);
//merge two nodes
x = make_tree(e1.ptree, e2.ptree);
e.key = x->weight = e1.key+e2.key;
e.ptree = x;
insert_min_heap(&heap, e);
}
e = delete_min_heap(&heap); //final huffman binary tree
destroy_tree(e.ptree);
}
void main(){
int freq[] = {15, 12, 8, 6, 4};
huffman_tree(freq, 5);
}