[자료구조] Queue C

K근형·2023년 12월 23일
0

자료구조

목록 보기
7/12

✔️ 배열을 이용한 큐

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

#pragma waring (disable : 4996)

#define MAX_SIZE 5

typedef struct queue
{
    int arr[MAX_SIZE]; //큐로 사용할 배열
    int front;         //큐의 삭제 위치
    int rear;          //큐의 삽입 위치
    int count;         //저장된 원소의 개수

}queue;

void createQueue(queue* p);
void enqueue(queue* p, int data);
int dequeue(queue* p);
void displayQueue(queue* p);
void clearQueue(queue* p);

int main()
{
    queue que;         //큐 구조체 변수 선언
    int choice, data;

    createQueue(&que);
    while (1)
    {
        system("clear");
        printf("\n\nt *** 배열 리스트를 이용한 원형 큐***\n");
        printf("1. enqueue    2. dequeue    3. print    4.clear    0.terminate\n ");
        printf("choice: ");
        scanf("%d", &choice);

        switch (choice)
        {
            case 1:
                printf("\n\n삽입할 정수를 입력하세요: ");
                scanf("%d", &data);
                enqueue(&que, data);
                break;
            case 2:
                data = dequeue(&que); //삭제된 값 리턴
                if (data != -1)
                    printf("\n\n\t\t%d dequeue!\n", data);
                break;
            case 3:
                displayQueue(&que);
                break;
            case 4:
                clearQueue(&que);
                break;
            case 0:
                return 0;
        }

        printf("\n\n\t\t");
        system("read");
    }

    return 0;

}

void createQueue(queue* p)
{
    p->front = 0;
    p->rear = 0;
    p->count = 0;
}

void enqueue(queue* p, int data)
{
    if(p->count == MAX_SIZE) //저장된 원소의 개수 == 배열의 최대크기
    {
        printf("\n\n\t\tQueue overflow\n");
        return;
    }
    p->arr[p->rear] = data;
    (p->rear)++; //저장 위치를 1 증가
    (p->count)++; //원소의 개수 1 증가

    if(p->rear == MAX_SIZE) //존재하지 않는 첨자
        p->rear = 0; //원형 형태로 만들기 위해
}

int dequeue(queue* p)
{
    if (p->count == 0)
    {
        // 더 이상 삭제할 수 없는 상태
        printf("\n\n\t\tqueue underflow\n");
        return -1;
    }

    int delVaue = p->arr[p->front]; //삭제할 값 저장
    (p->front)++; //삭제할 위치를 1증가
    (p->count)--; //저장된 원소의 개수는 1감소

    if(p->front == MAX_SIZE) //존재하지 않는 첨자라면?
    {
        p->front = 0; //0번 위치로 이동
    }

    return delVaue; //삭제된 값을 리턴
}

void displayQueue(queue* p)
{
    if (p->count == 0)
    {
        printf("\n\n\t\t출력할 데이터가 존재하지 않습니다.");
        return;
    }

    system("clear");
    printf("\n\ncircular queue display(FIFO): ");

    for(int i = p->front; i < p->front + p->count; i++)
    {
        //p->arr[3 % 5], p->arr[4 % 5], p->arr[5 % 5], p->arr[6 % 5]
        printf("%d ", p->arr[i % MAX_SIZE]);
    }
    puts("");
}

void clearQueue(queue* p)
{
    //실제 데이터가 삭제되는 것은 아니다.
    //삭제 된 것처럼 코드로 구현 -> 논리적인 삭제
    p->front = p->rear = p->count = 0;
}

✔️ 연결리스트를 이용한 큐

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

#pragma waring (disable : 4996)

typedef struct node
{
    int value;
    struct node* next;
}node;

node* head = NULL;
node* tail = NULL;

int dequeue();
void displayQueue();
void clearQueue();
void enqueue(int data);

int main()
{
         
    int choice, data;

    while (1)
    {
        system("clear");
        printf("\n\nt *** 배열 리스트를 이용한 원형 큐***\n");
        printf("1. enqueue    2. dequeue    3. print    4.clear    0.terminate\n ");
        printf("choice: ");
        scanf("%d", &choice);
      
        switch (choice)
        {
            case 1:
                printf("\n\n삽입할 정수 입력: ");
                scanf("%d", &data);
                enqueue(data);
                break;
            case 2:
                data = dequeue(); //삭제된 값 리턴
                if (data != -1)
                    printf("\n\n\t\t%d dequeue!\n", data);
                break;
            case 3:
                displayQueue();
                break;
            case 4:
                clearQueue();
                break;
            case 0:
                clearQueue();
                return 0;
        }
     
        printf("\n\n\t\t");
        system("read");
    }

    return 0;

}


int dequeue()
{
    // 맨 앞 삭제
    if(head == NULL)
    {
        // 더이상 삭제할 수 없는 상태
        printf("\n\n\t\tQueue underflow\n");
        return -1;
    }
  
    //실제 삭제되는 코드: 물리적인 삭제
    node* delNode = head;
    head = head->next;
    int delValue = delNode->value; //삭제할 값 저장
    free(delNode); //삭제

    if(head == NULL)
        tail = NULL;
    return delValue; //삭제된 값 리턴
}

void displayQueue()
{
    if (head == NULL)
    {
        printf("\n\n\t\t저장 된 데이터가 없습니다.\n");
        return;
    }

    system("clear");
    printf("\nQueue display(FIFO): ");
    node* curNode = head;

    while (curNode) //방문 노드가 있다면? (마지막 노드까지 순회)
    {
        printf("%d ", curNode->value);
        curNode = curNode->next;
    }
    puts("");
}

void clearQueue()
{
    if (head == NULL)
    {
        return;
    }

    //실직적인 삭제(물리적인 삭제 수행된다.)
    // 모든 노드 제거
    // 첫 노드 제거 -> 반복
    while(head) // head != NULL
    {
        node* delNode = head;
        head = head->next;
        free(delNode); //삭제
    }
}

void enqueue(int data)
{
    //맨 뒤 추가
    node* newNode;
    newNode = (node*)malloc(sizeof(node));
    newNode->value = data;
    newNode->next = NULL;

    if(head == NULL)
    {
        //새 노드는 첫 노드이자 마지막 노드
        head = newNode;
        tail = newNode;
        return;
    }

    tail->next = newNode;
    tail = newNode; //새 노드가 마지막에 추가
}

✔️ Survival c

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

#pragma warning (disable : 4996)

typedef struct DNode
{
    int value;
    struct DNode* prev;
    struct DNode* next;
}DNode;

DNode* head = NULL;
DNode* tail = NULL;

void displayQueue();
void standBy(int n);
void killer(int killN);
void removeFirstDNode();
void removeTailDNode();


int main()
{
    int n;
    printf("처형을 기다리는 사람은 몇 명 입니까? ");
    scanf("%d", &n);
    standBy(n);
    displayQueue();

    int killN;
    printf("몇 번째 사람을 처형하시겠습니까? ");
    scanf("%d", &killN);
    killer(killN);
    displayQueue();

    return 0;
}

void displayQueue()
{
    if (head == NULL)
    {
        printf("\n\n\t\t저장 된 데이터가 없습니다.\n");
        return;
    }

    //system("clear");
    printf("\n큐에 대기중인 사람의 명단: ");
    DNode* curNode = head;

    while (curNode) //방문 노드가 있다면? (마지막 노드까지 순회)
    {
        printf("%d ", curNode->value);
        curNode = curNode->next;
    }
    puts("");
}

void standBy(int n)
{
    DNode* newNode;
    for(int i = 1; i <= n; i++)
    {
        newNode = (DNode*)malloc(sizeof(DNode));
        newNode->value = i;
        newNode->next = NULL;
        newNode->prev = NULL;

        if(head == NULL)
        {
            head = newNode;
            tail = newNode;
        }
        else
        {
            //맨 뒤에 연결
            tail->next = newNode;
            newNode->prev = tail;
            tail = newNode;
        }
    }
}

void removeFirstDNode()
{
    DNode* delNode;
    if (head == NULL)
    {
        printf("\n\n\t\t연결리스트가 구성되지 않아 삭제할 데이터가 없습니다.\n");
        return;
    }

    delNode = head;
    head = head->next;
    free(delNode);

    if (head != NULL)
    {
        head->prev = NULL;
    }

    if (head == NULL)
    {
        tail = NULL;
    }
}

void removeTailDNode()
{
    DNode* delNode;
    if (head == NULL)
    {
        printf("\n\n\t\t연결리스트가 구성되자 않아 삭제할 데이터가 없습니다.\n");
        return;
    }

    delNode = tail;
    tail = tail->prev;
    free(delNode);
    printf("\n\n\t\t마지막 노드가 제거됐습니다.\n");

    if(tail != NULL)
    {
        tail->next = NULL;
    }

    if(tail == NULL)
    {
        head = NULL;
    }
}

void killer(int killN)
{
    if (head == NULL)
    {
        return;
    }

    DNode* curNode = head;
    DNode* delNode;
    int isEnd = 0; //끝이야?

    while (isEnd == 0)//while(!isEnd) //노드의 끝이 아니라면 반복
    {
        for(int i = 1; i < killN; i++) //삭제할 위치로 이동
        {
           curNode = curNode->next;
           if(curNode == NULL)
           {
               isEnd = 1; //노드의 끝
               break;
           }
        }
        if (isEnd == 0) //if (!isEnd)
        {
            delNode = curNode; // 이 위치가 삭제할 위치
            curNode = curNode->next; // 삭제할 위치 다음으로 이동

            if(delNode == head) //첫 노드를 제거하는 경우 => head가 변경
            {
                removeFirstDNode();
                /*
                head = head->next;

                if(head != NULL)
                    head->prev = NULL; // 이전 노드가 없음
                    free(delNode);


                if (head == NULL)
                    tail = NULL;
                 */
            }
            else if (delNode == tail) //마지막 노드를 제거하는 경우 => tail이 변경
            {
                removeTailDNode();
                isEnd = 1;
            }

            else
            {
                //일반적인 경우
                delNode->prev->next = delNode->next;
                delNode->next->prev = delNode->prev;
                free(delNode);
                printf("\n\n\t\t일반적인 노드 제거\n");
            }
        }
    }
}
profile
진심입니다.

0개의 댓글