1-1. What is priority queue
- 이 것을 큐라고 생각을 하면 안된다.
- 그냥 데이터를 우선순위로 순서대로 저장을 하고, 들어간 순서에 상관 없이 우선순의 근거로 데이터를 제거한다.
- 우선순위 큐는 배열, 리스트, 힙을 이용하여 구현을 할 수 있다.
- 이때 우선순위 기준은 이 자료구조를 쓰는 프로그래머가 정하면 된다.
1-2. heap
- 힙은 그냥 완전 이진 트리이다.
- 부모 노드는 자식 노드보다 항상 우선 순쉬가 높아야 한다.
- 근데 형제간의 우선순위는 잘 모른다.
// 최대힙(우선순위가 높다는 것은 노드의 저장 값이 크다는 것이다. - 모든 부모 노드의 저장값이 자식의 노드의 저장값보다 크다. - 즉 루트노드의 값이 가장 크다.
// 최소 힙(우선순위가 높다는 것은 노드의 저장 값이 가장 작다는 것) - 모든 부모 노드의 저장 값이 자식의 노드의 저장값보다 작다. - 즉, 루트 노드의 저장 값이 가장 작다.
1-3. 힙의 저장과정
1-4. 힙의 삭제과정
1-5. 삽입과 삭제 과정의 우선수위 큐의 빅오
1-6. Create heap with array
1-7. simply heap source
typedef char HData;
typedef int Priority
typedef struct _heapElem
{
Priority pr; // 값이 적을수록 높은 우선순위
HData data;
}HeapElem;
typedef struct _heap
{
int numOfData;
HeapElem heapArr[HEAP_LEN];
}Heap;
void HeapInit(Heap *ph)
{
ph -> numOfData = 0;
}
int HIsEmpty(Heap *ph)
{
if(ph -> numOfData == 0)
return TRUE;
else
return FALSE;
}
int GetParentIDX(int idx)
{
return idx/2;
}
int GetLChildIDX(int idx)
{
return 2*idx;
}
int GetRChildIDX(int idx)
{
//return idx*2 + 1;
return GetLChildIDX(idx)+1;
}
// 가장 높은 우선 순위의 자식의 인덱스를 반환 근데
// 배열기반 힙은 0인덱스를 비우고 시작하니
// 노드의 자기 번호가 고유이자 배열의 인덱스
// 힙은 완전이진트리이다. 꼭기억
int GetHiPriChildIDX(Heap * ph, int idx)
{
// 자식이 없으면 0 반환
if (ph -> numOfData < GetLChildIDX(idx))
return 0;
else if(ph -> numOfData == GetLChildIDX(idx))
return GetLChildIDX(idx);
else
{
/// comp 함수는 우선순위를 비교를 위한 함수
if(ph -> comp(ph->heapArr[GetLChildIDX(idx)], ph->heapArr[GetRChildIDX(idx)] < 0)
return GetRChildIDX(idx);
else
return GetLChildIDX(idx);
}
}
void HInsert(Heap * ph, HData data, Priority pr)
{
int idx = ph -> numOfData +1;
HeapElem nelem = {pr, data};
// new node locates the new while comparing with parent node
while(idx != 1)
{
if(pr < (ph->heapArr[GetParentIDX(idx)].pr)) // if new node is up
{
ph -> heapArr[idx] = ph->heapArr[GetParentIDX(idx)];
idx = GetParentIDX(idx);
}
else
break;
}
ph->heapArr[idx] = nelem;
ph -> numOfData += 1;
}
HData HDelete(Heap *ph)
{
HData retData = (ph -> heapArr[1]).data;
HeapElem lastElem = ph -> heapArr[ph -> numOfData];
int parentIdx = 1;
int chilIdx;
while(childIdx = GetHiPriChildIDX(ph, parentIdx))
{
if (lastElem.pr <= ph->heapArr[childIdx].pr)
break;
ph->heapArr[parentIdx] = ph -> heapArr[childIdx];
parentIdx = childIdx;
}
ph -> heapArr[parentIdx] = lastElem;
ph -> numOfData -= 1;
return retData;
}
/// main function part
int main ()
{
Heap heap;
HeapInit(&heap);
HInsert(&heap, 'A', 1);
HInsert(&heap, 'B', 2);
HInsert(&heap, 'C', 3);
printf("%c \n", HDelete(&heap));
HInsert(&heap, 'A', 1);
HInsert(&heap, 'B', 2);
HInsert(&heap, 'C', 3);
printf("%c \n", HDelete(&heap));
while (!HIsEmpty(&heap))
printf("%c \n", HDelete(&heap));
return 0;
}
// result of main function
A A B B C C
// 데이터 우선순위를 함께 전달하기 보다는 데이터를 근거로 하여 데이터의 우선 순위를 정하는 방식이 더욱 좋을 수도 있다.