λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
βœ’οΈ Data Structures & Algorithms

[Data Structures & Algorithms] 큐(Queue)의 이해와 μ•Œκ³ λ¦¬μ¦˜ (μ—°κ²° 큐, 순차 큐, μ›ν˜• 큐)

by A Lim Han 2023. 6. 11.

πŸ¦„ 큐(Queue)λž€?

큐(Queue)λŠ” λ°μ΄ν„°μ˜ μ‚½μž…κ³Ό μ‚­μ œκ°€ 각각 λ‹€λ₯Έ λμ—μ„œ μ΄λ£¨μ–΄μ§€λŠ” μ„ ν˜• 자료ꡬ쑰둜, "μ„ μž…μ„ μΆœ(FIFO, First-In-First-Out)" 원칙을 λ”°λ₯Έλ‹€.

μŠ€νƒκ³Ό λ§ˆμ°¬κ°€μ§€κ³  μ‚½μž…κ³Ό μ‚­μ œ μœ„μΉ˜κ°€ μ œν•œλ˜μ–΄ 있으며 λ’· λΆ€λΆ„μ—μ„œλŠ” μ‚½μž…λ§Œμ„, μ•ž λΆ€λΆ„μ—μ„œλŠ” μ‚­μ œ μž‘μ—…λ§Œμ„ μˆ˜ν–‰ν•  수 μžˆλŠ” ꡬ쑰λ₯Ό 가진닀.

 


 

πŸ’œ 큐(Queue)와 μŠ€νƒ

μ—°μ‚° ν•­λͺ© μ‚½μž… μ—°μ‚° μ‚­μ œ μ—°μ‚°
자료ꡬ쑰 μ—°μ‚°μž μ‚½μž… μœ„μΉ˜ μ—°μ‚°μž μ‚­μ œ μœ„μΉ˜
Stack push top pop top
Queue enQueue rear deQueue front

 


 

πŸ’œ 큐(Queue)의 좔상 μžλ£Œν˜•

ADT Queue

    //곡백 큐 생성
    createQueue() ::= create an empty Q;
    
    //큐가 곡백 μƒνƒœμΈμ§€ 검사
    isEmpty(Q) ::= if (Q is empty) then return true
                   else return false;
    
    //큐의 rear에 μ›μ†Œ μ‚½μž…
    enQueue(Q, item) ::= insert item at the rear of Q;
    
    //큐의 front에 μžˆλŠ” μ›μ†Œ μ‚­μ œ
    deQueue(Q) ::= if (isEmpty(Q)) then return error
                   else
                   {
                       delete and return the front item Q
                   };
                   
    //큐의 front에 μžˆλŠ” μ›μ†Œ λ°˜ν™˜
    peek(Q) ::= if (isEmpty(Q)) then return error
                else
                {
                    return the front item of the Q
                };
     
End Queue

 


 

πŸ¦„ 순차 큐(Queue)의 κ΅¬ν˜„κ³Ό μ•Œκ³ λ¦¬μ¦˜

πŸ’œ 순차 자료ꡬ쑰λ₯Ό μ΄μš©ν•œ 순차 큐(Queue)의 κ΅¬ν˜„

ⓐ 1차원 배열을 μ΄μš©ν•œ 큐

  • 큐의 크기  ==  λ°°μ—΄ 크기
  • λ³€μˆ˜ front  ==  μ €μž₯된 첫 번째 μ›μ†Œμ˜ 인덱슀
  • λ³€μˆ˜ rear  ==  μ €μž₯된 λ§ˆμ§€λ§‰ μ›μ†Œμ˜ 인덱슀

 

β“‘ μƒνƒœ ν‘œν˜„

  • front의 초기 μƒνƒœ  ==  rear의 초기 μƒνƒœ  ==  - 1
  • 곡백 μƒνƒœμΌ λ•ŒλŠ” front  ==  rear
  • rear  ==  n - 1 이라면 포화 μƒνƒœ

 


 

πŸ’œ 순차 큐(Queue) 생성 μ•Œκ³ λ¦¬μ¦˜

β‘  μˆœμ°¨ 큐(Queue) 생성 μ•Œκ³ λ¦¬μ¦˜

createQueue()

    Q[n]; //크기가 n인 1차원 λ°°μ—΄ 생성
    front <- - 1; //front의 크기λ₯Ό -1둜 μ΄ˆκΈ°ν™”
    rear <- - 1; //rear의 크기λ₯Ό -1둜 μ΄ˆκΈ°ν™”
    
end createQueue()

 

 

β‘‘ μˆœμ°¨ 큐(Queue) 곡백 μƒνƒœκ²€μ‚¬ μ•Œκ³ λ¦¬μ¦˜

isEmpty(Q)

    if (front == rear) //rearκ°’κ³Ό front값이 κ°™μœΌλ©΄ 곡백 μƒνƒœ
    {
        return true;
    }
    else
    {
        return false;
    }
    
end isEnpty()

 

 

β‘’ 순차 큐(Queue) 포화 μƒνƒœκ²€μ‚¬ μ•Œκ³ λ¦¬μ¦˜

isFull(Q)

    if (n - 1 == rear)
    {
        return true; //포화 μƒνƒœ
    }
    else
    {
        return false;
    }
    
end isFull()

 

 

β‘£ μˆœμ°¨ 큐(Queue) μ‚½μž… μ•Œκ³ λ¦¬μ¦˜

enQueue(Q, item)

    if (isFull(Q))
    {
        Queue_Full(); //큐가 포화 μƒνƒœμΌ 경우 μ‚½μž… λΆˆκ°€
    }
    else
    {
        rear <- rear + 1; //λ§ˆμ§€λ§‰ μ›μ†Œμ˜ 인덱슀λ₯Ό μ €μž₯ν•œ rear κ°’ 1 증가
        Q[rear] <- item; //μˆ˜μ •λœ rear값에 ν•΄λ‹Ήν•˜λŠ” μ›μ†Œμ— item μ €μž₯
    }
    
end enQueue()

 

 

β‘€ μˆœμ°¨ 큐(Queue) μ‚­μ œ μ•Œκ³ λ¦¬μ¦˜

deQueue(Q)

    if (isEmpty(Q))
    {
        Queue_Empty(); //큐가 곡백 μƒνƒœμΌ 경우 μ‚­μ œ λΆˆκ°€
    }
    else
    {
        front <- front + 1; //front의 μœ„μΉ˜λ₯Ό ν•œ 자리 λ’€λ‘œ 이동
        return Q[front]; //front 자리의 μ›μ†Œλ₯Ό μ‚­μ œ ν›„ λ°˜ν™˜
    }
    
end deQueue()

 

 

β‘₯ μˆœμ°¨ 큐(Queue) 검색 μ•Œκ³ λ¦¬μ¦˜

peek(Q)

    if (isEmpty(Q))
    {
        Queue_Empty(); //큐가 곡백 μƒνƒœμΌ 경우 검색 λΆˆκ°€
    }
    else
    {
        return Q[front + 1]; //큐에 μžˆλŠ” 첫 번째 μ›μ†Œ λ°˜ν™˜
    }
    
end peek()

 


 

πŸ¦„ μ›ν˜• 큐의 κ΅¬ν˜„κ³Ό μ›ν˜• 큐 μ•Œκ³ λ¦¬μ¦˜

πŸ’œ μ›ν˜• 큐(Queue)의 κ΅¬ν˜„

β‘  초기 곡백 μƒνƒœ

  • front = rear = 0

β‘‘ 순차 큐와 μ›ν˜• 큐의 비ꡐ

μ’…λ₯˜ μ‚½μž… μœ„μΉ˜ μ‚­μ œ μœ„μΉ˜
순차 큐 rear = rear + 1 front = front + 1
μ›ν˜• 큐 rear = ( rear + 1 ) mod n front = ( front + 1 ) mod n

 

β‘’ μ‚¬μš© 쑰건

  • 곡백 μƒνƒœμ™€ 포화 μƒνƒœ ꡬ뢄을 μœ„ν•΄ frontκ°€ μžˆλŠ” μžλ¦¬λŠ” 항상 κ³΅λž€μœΌλ‘œ λ‘”λ‹€.

 


 

πŸ’œ μ›ν˜• 큐(Queue) 생성 μ•Œκ³ λ¦¬μ¦˜

β‘  μ›ν˜• 큐(Queue) 생성 μ•Œκ³ λ¦¬μ¦˜

createQueue()

    cQ[n]; //크기가 n인 1차원 λ°°μ—΄ 생성
    front <- 0; //front의 크기λ₯Ό 0으둜 μ΄ˆκΈ°ν™”
    rear <- 0; //rear의 크기λ₯Ό 0으둜 μ΄ˆκΈ°ν™”
    
end createQueue()

 

 

β‘‘ μ›ν˜• 큐의 곡백 μƒνƒœ 검사 μ•Œκ³ λ¦¬μ¦˜

isEmpty(Q)

    if (front == rear) //rearκ°’κ³Ό front값이 κ°™μœΌλ©΄ 곡백 μƒνƒœ
    {
        return true;
    }
    else
    {
        return false;
    }
    
end isEnpty()

 

 

β‘’ μ›ν˜• 큐의 포화 μƒνƒœ 검사 μ•Œκ³ λ¦¬μ¦˜

isFull(Q)

    if (((rear + 1) mod n) == front)
    {
        return true; //포화 μƒνƒœ
    }
    else
    {
        return false;
    }
    
end isFull()

 

 

β‘£ μ›ν˜• 큐(Queue) μ‚½μž… μ•Œκ³ λ¦¬μ¦˜

enQueue(cQ, item)

    if (isFull(cQ))
    {
        Queue_Full(); //큐가 포화 μƒνƒœμΌ 경우 μ‚½μž… λΆˆκ°€
    }
    else
    {
        rear <- (rear + 1) mod n;
        cQ[rear] <- item;
    }
    
end enQueue()

 

 

β‘€ μ›ν˜• 큐(Queue) μ‚­μ œ μ•Œκ³ λ¦¬μ¦˜

deQueue(cQ)

    if (isEmpty(cQ))
    {
        Queue_Empty(); //큐가 곡백 μƒνƒœμΌ 경우 μ‚­μ œ λΆˆκ°€
    }
    else
    {
        front <- (front + 1) mod n;
        return cQ[front];
    }
    
end deQueue()

 


 

πŸ¦„ μ—°κ²° 큐(Queue)의 κ΅¬ν˜„κ³Ό μ•Œκ³ λ¦¬μ¦˜

πŸ’œ μ—°κ²° 자료ꡬ쑰λ₯Ό μ΄μš©ν•œ μ—°κ²° 큐(Queue)의 κ΅¬ν˜„

β‘  μ—°κ²° 큐

: λ‹¨μˆœ μ—°κ²° 리슀트λ₯Ό μ΄μš©ν•œ 큐

  • 큐의 μ›μ†Œ = λ‹¨μˆœ μ—°κ²° 리슀트의 λ…Έλ“œ
  • 큐의 μ›μ†Œμ˜ μˆœμ„œ = λ…Έλ“œμ˜ 링크 ν¬μΈν„°λ‘œ μ—°κ²°
  • λ³€μˆ˜ front = 첫 번째 λ…Έλ“œλ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터 λ³€μˆ˜
  • λ³€μˆ˜ rear = λ§ˆμ§€λ§‰ λ…Έλ“œλ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터 λ³€μˆ˜

 

β‘‘ 포화 μƒνƒœμ™€ 초기 μƒνƒœ ν‘œν˜„

  • rear = front = null

 


 

πŸ’œ μ—°κ²° 큐(Queue)와 μ•Œκ³ λ¦¬μ¦˜

β‘  μ—°κ²° 큐(Queue) 생성 μ•Œκ³ λ¦¬μ¦˜

createLinkedQueue()

    front <- NULL;
    rear <- NULL;
    
end createLinkedQueue()

 

 

β‘‘ μ—°κ²° 큐(Queue) 곡백 μƒνƒœκ²€μ‚¬ μ•Œκ³ λ¦¬μ¦˜

isEmpty(LQ)

    if (front == NULL) //곡백 μƒνƒœ
    {
        return true;
    }
    else
    {
        return false;
    }
    
end isEnpty()

 

 

β‘’ μ—°κ²° 큐(Queue) μ‚½μž… μ•Œκ³ λ¦¬μ¦˜

enQueue(LQ, item)

    new <- getNode();
    new.data <- item; //데이터 ν•„λ“œμ— item μ €μž₯
    new.link <- NULL; //μ‚½μž…ν•  μƒˆ λ…Έλ“œλŠ” μ—°κ²° 큐의 λ§ˆμ§€λ§‰ λ…Έλ“œκ°€ λ˜μ–΄μ•Ό 함
    
    if (front == NULL) //큐가 곡백 μƒνƒœμΈ 경우
    {
        //포인터 rearκ³Ό frontκ°€ λͺ¨λ‘ μƒˆ λ…Έλ“œλ₯Ό 가리킀도둝 μ„€μ •
        rear <- new;
        front <- new;
    }
    else //큐가 곡백 μƒνƒœκ°€ μ•„λ‹Œ 경우
    {
        rear.link <- new;
        rear <- new;
    }
    
end enQueue()

 

 

β‘£ μ—°κ²° 큐(Queue) μ‚­μ œ μ•Œκ³ λ¦¬μ¦˜

deQueue(LQ)

    if (isEmpty(LQ))
    {
        Queue_Empty(); //큐가 곡백 μƒνƒœμΌ 경우 μ‚­μ œ λΆˆκ°€
    }
    else
    {
        old <- front;
        item <- front.data;
        front <- front.link;
        
        if (isEmpty(LQ))
        {
            rear <- NULL;
        }
        
        returnNode(old); //포인터 oldκ°€ 가리킀고 μžˆλŠ” λ…Έλ“œ μ‚­μ œ ν›„ λ©”λͺ¨λ¦¬ 곡간 λ°˜ν™˜
        return item;
    }
    
end deQueue()

 

 

β‘€ μ—°κ²° 큐(Queue) 검색 μ•Œκ³ λ¦¬μ¦˜

peek(LQ)

    if (isEmpty(LQ))
    {
        Queue_Empty(); //큐가 곡백 μƒνƒœμΌ 경우 검색 λΆˆκ°€
    }
    else
    {
        return (front.data); //μ—°κ²° 큐의 첫 번째 λ…Έλ“œμ˜ 데이터 ν•„λ“œκ°’ λ°˜ν™˜
    }
    
end peek()