7.21.2017

자료구조 PriorityQueue

//PriorityQueue.h 헤더파일 만들기

#ifndef PRIORITYQUEUE_H
#define PRIORITYQUEUE_H

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

typedef int PriorityType;

typedef struct tagPQNode {
        PriorityType Priority;
        void* Data;
}PQNode;

typedef struct tagPriorityQueue {
        PQNode* Nodes;
        int Capacity;
        int UsedSize;
}PriorityQueue;

PriorityQueue* Create(int InitialSize);
void Destroy(PriorityQueue* PQ);
void Enqueue(PriorityQueuePQPQNode NewData);
void Dequeue(PriorityQueuePQPQNode* Root);
int GetParent(int index);
int GetLeftChild(int index);
void SwapNodes(PriorityQueuePQint Index1int Index2);
void PrintNode(PriorityQueuePQ);
int IsEmpty(PriorityQueuePQ);

#endif

================================================================================

#include "PriorityQueue.h"

PriorityQueue* Create(int InitialSize){
        PriorityQueue* NewPQ = (PriorityQueue*)malloc(sizeof(PriorityQueue));
        NewPQ ->Capacity = InitialSize;
        NewPQ ->UsedSize = 0;
        NewPQ ->Nodes = (PQNode*)malloc(sizeof(PQNode)*NewPQ ->Capacity);

        printf("size : %d\n"sizeof(PQNode));

        return NewPQ ;
}

void Destroy(PriorityQueuePQ){
        free(PQ->Nodes);
        free(PQ);
}

void Enqueue(PriorityQueuePQPQNode NewNode){
        int CurrentPosition = PQ->UsedSize;
        int ParentPosition = GetParent(CurrentPosition);

        if (PQ->UsedSize == PQ ->Capacity) {
                PQ->Capacity *= 2;
                PQ->Nodes = (PQNode*)realloc(PQ->Nodes, sizeof(PQNode)*PQ->Capacity);
        }
        PQ->Nodes[CurrentPosition] = NewNode;

        while (PQ->Nodes[CurrentPosition].Priority < PQ->Nodes[ParentPosition].Priority) {
                SwapNodes(PQ, CurrentPosition, ParentPosition);

                CurrentPosition = ParentPosition;
                ParentPosition = GetParent(CurrentPosition);
        }
        PQ->UsedSize++;
}

void Dequeue(PriorityQueuePQPQNodeRoot){
        int ParentPosition = 0;
        int LeftPosition = 0;
        int RightPosition = 0;

        memcpy(Root, &PQ->Nodes[0], sizeof(PQNode));
        memset(&PQ->Nodes[0], 0, sizeof(PQNode));
        PQ->UsedSize--;
        SwapNodes(PQ, 0, PQ->UsedSize);

        LeftPosition = GetLeftChild(0);
        RightPosition = LeftPosition + 1;
        while (1) {
                int SelectedChild = 0;
                //자식이 없는 경우
                if (LeftPosition >= PQ->UsedSize) break;

                //오른쪽에 자식이 없는 경우(왼쪽에만 있는 경우)
                if (RightPosition >= PQ->UsedSize)
                        SelectedChild = LeftPosition;
                else { //양쪽 모두 자식이 있는 경우
                        if (PQ->Nodes[LeftPosition].Priority > PQ->Nodes[RightPosition].Priority)
                                SelectedChild = RightPosition;
                        else SelectedChild = LeftPosition;
                }

                if (PQ->Nodes[ParentPosition].Priority > PQ->Nodes[SelectedChild].Priority) {
                        SwapNodes(PQ, ParentPosition, SelectedChild);
                ParentPosition = SelectedChild;
                }
                else {
                        break;
                }
                LeftPosition = GetLeftChild(ParentPosition);
                RightPosition = LeftPosition + 1;
}
        if (PQ->UsedSize < (PQ->Capacity) / 2) {
                PQ->Capacity /= 2;
        }
}

int GetParent(int index) {
        return (index - 1) / 2;
}

int GetLeftChild(int index){
        return (2 * index) + 1;
}

void SwapNodes(PriorityQueuePQint Index1int Index2){
        int CopySize = sizeof(PQNode);
        PQNode* Temp = (PQNode*)malloc(CopySize);
        memcpy(Temp, &PQ->Nodes[Index1], CopySize);
        memcpy(&PQ->Nodes[Index1], &PQ->Nodes[Index2], CopySize);
        memcpy(&PQ->Nodes[Index1], Temp, CopySize);
        free(Temp);
}

void PrintNode(PQNodeNode){
        printf("작업 명 : %s (우선순위:%d)\n"Node->Data, Node->Priority);
}

int IsEmpty(PriorityQueuePQ){
        return (PQ->UsedSize == 0);
}

void main() {
        PriorityQueue* PQ = Create(3);
        PQNode Popped;

        PQNode Nodes[7] = {
                {34,(void*)"코딩"},
                {12,(void*)"수업"},
                {87,(void*)"커피마시기"},
                {45,(void*)"문서작성"},
                {35,(void*)"디버깅"},
                {66,(void*)"이닦기"}
        };

        for (int i = 0; i < 6; i++) {
                Enqueue(PQ, Nodes[i]);
        }
        printf("큐에 남아 있는 작업의 수 : %d\n", PQ->UsedSize);

        while (!IsEmpty(PQ)) {
                Dequeue(PQ, &Popped);
                PrintNode(&Popped);
        }
}

댓글 없음:

댓글 쓰기