C# - 일반화 큐

양규빈·2023년 7월 19일
0

C# 공부

목록 보기
18/30

개요

일련의 요소를 선입선출(FIFO, First-In-First-Out) 원칙에 따라 관리하는 데이터 구조이다. 큐는 요소를 추가할 때는 뒤쪽(Enqueue)에, 요소를 제거할 때는 앞쪽(Dequeue)에서 수행한다.

제너릭 큐는 System.Collections.Generic 네임스페이스에 포함되어 있으며, 제너릭 타입을 사용하여 다양한 데이터 형식의 요소를 저장할 수 있다.

제너릭(Generic) 기능을 활용하여 선언된 큐는 특정한 데이터 형식의 요소만을 저장할 수 있다. 예를 들어, Queue<int>는 정수형 요소만을 저장하는 큐를 생성한다. 이를 통해 요소의 데이터 형식을 명시하고 박싱과 언박싱이 발생하지 않도록 한다.

Queue<T> - Queue의 기능 + 제너릭(Boxing, Unboxing 없음)
-기존 컬렉션의 성능 문제를 개선
-미리 타입을 지정해서 코드 오류를 미리 처리 가능하다

코드 및 세부 설명

맴버함수

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main(string[] args)
    {
        Queue<int> queue = new Queue<int>();

        // Enqueue: 요소 추가
        queue.Enqueue(10);
        queue.Enqueue(20);
        queue.Enqueue(30);

        // Dequeue: 요소 제거 및 반환
        int firstElement = queue.Dequeue();
        Console.WriteLine("Dequeued element: " + firstElement); // 출력: 10

        // Peek: 요소 확인
        int nextElement = queue.Peek();
        Console.WriteLine("Next element: " + nextElement); // 출력: 20

        // Count: 큐에 저장된 요소 개수
        int count = queue.Count;
        Console.WriteLine("Queue count: " + count); // 출력: 2

        // Clear: 큐 비우기
        queue.Clear();
        Console.WriteLine("Queue count after clearing: " + queue.Count); // 출력: 0
    }
}
  • Enqueue(T item): 큐의 뒤쪽에 요소를 추가한다.
  • Dequeue(): 큐의 앞쪽에서 요소를 제거하고 반환한다.
  • Peek(): 큐의 앞쪽에 위치한 요소를 반환한다. 제거하지는 않는다.
  • Count: 큐에 저장된 요소의 개수를 가져온다.
  • Clear(): 큐의 모든 요소를 제거한다.

기본적인 큐의 사용법이다.
Enqueue를 통해서, 데이터를 삽입하고,
배열의 데이터를 바로 초기화 하는 것도 가능하다.

스택과 마찬가지로 CopyTo를 이용하여, 동적 배열 내에 Queue값을 가져와 저장할 수 있다.

두 개의 큐를 이용하여 스택을 구현

//Queue를 Stack처럼 사용할 수 있도록 바꾼 코드.
        class StackLike<T> where T: struct
        {
            Queue<T> InputQueue;
            Queue<T> OutputQueue;

            public StackLike()
            {
                InputQueue= new Queue<T>();
                OutputQueue= new Queue<T>();
            }

            //값을 넣음
            public void Push(T data)
            {
                InputQueue.Enqueue(data);
            }

            //push와 pop을 할 때, refreshData를 꼭 해주어야 한다.
            //input에 있는 큐들을 반대로 만듦.
            private void RefreshData()
            {
                while(InputQueue.Count > 0 && OutputQueue.Count <= 0) 
                {
                    foreach (var item in InputQueue.Reverse<T>())
                    {
                        OutputQueue.Enqueue(item);
                    }
                    InputQueue.Clear();
                }
            }

            public T Pop()
            {
                RefreshData();

                if(OutputQueue.Count <= 0)
                {
                    throw new Exception("Stack이 없습니다.");
                }
                return OutputQueue.Dequeue();

            }

            public T Peek()
            {
                RefreshData();
                if (OutputQueue.Count <= 0)
                {
                    throw new Exception("Stack이 없습니다.");
                }
                return OutputQueue.Peek();
            }
        }

이것은 C#을 사용하여 두 개의 큐를 이용하여 스택 자료구조를 구현한 것이다.
이 클래스는 제네릭으로 작성되어 있어 사용자가 스택에 저장할 요소의 데이터 타입을 정의할 수 있다.

생성자는 InputQueue와 OutputQueue 두 개의 큐를 초기화한다.
Push 메서드는 주어진 요소를 InputQueue에 Enqueue한다.

Pop 및 Peek 메서드는 RefreshData 메서드를 사용하여 구현되며, 이 메서드는 InputQueue의 요소를 OutputQueue로 교환한다.
RefreshData 메서드는 private로 선언되어 있으며, Pop과 Peek 모두에서 데이터가 스택의 올바른 순서로 유지되도록 호출된다.

Pop 메서드는 OutputQueue에서 가장 위의 요소를 Dequeue하고 반환한다.
OutputQueue가 비어있으면 예외가 발생한다.
Peek 메서드는 맨 위의 요소를 제거하지 않고 반환한다.
OutputQueue가 비어있으면 예외가 발생한다.

참고로 클래스 정의에 있는 where T: struct 제약 조건은 타입 매개변수 T를 값 형식, 예를 들어 정수나 구조체와 같은 값 타입으로 제한한다. 클래스와 같은 참조 타입은 허용되지 않는다.

profile
훌륭한 개발자를 꿈꾸는 중입니다

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

많은 도움이 되었습니다, 감사합니다.

답글 달기