# ์Šคํƒ & ํ



# ์Šคํƒ(Stack)

์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์ด ํ•œ ๊ณณ(๋ฐฉํ–ฅ)์œผ๋กœ ์ œํ•œ

# LIFO (Last In First Out, ํ›„์ž…์„ ์ถœ) : ๊ฐ€์žฅ ๋‚˜์ค‘์— ๋“ค์–ด์˜จ ๊ฒƒ์ด ๊ฐ€์žฅ ๋จผ์ € ๋‚˜์˜ด

์–ธ์ œ ์‚ฌ์šฉ?

ํ•จ์ˆ˜์˜ ์ฝœ์Šคํƒ, ๋ฌธ์ž์—ด ์—ญ์ˆœ ์ถœ๋ ฅ, ์—ฐ์‚ฐ์ž ํ›„์œ„ํ‘œ๊ธฐ๋ฒ•


๋ฐ์ดํ„ฐ ๋„ฃ์Œ : push()

๋ฐ์ดํ„ฐ ์ตœ์ƒ์œ„ ๊ฐ’ ๋บŒ : pop()

๋น„์–ด์žˆ๋Š” ์ง€ ํ™•์ธ : isEmpty()

๊ฝ‰์ฐจ์žˆ๋Š” ์ง€ ํ™•์ธ : isFull()

+SP


push์™€ popํ•  ๋•Œ๋Š” ํ•ด๋‹น ์œ„์น˜๋ฅผ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•˜๋ฏ€๋กœ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋Š” '์Šคํƒ ํฌ์ธํ„ฐ(SP)'๊ฐ€ ํ•„์š”ํ•จ

์Šคํƒ ํฌ์ธํ„ฐ๋Š” ๋‹ค์Œ ๊ฐ’์ด ๋“ค์–ด๊ฐˆ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์Œ (์ฒ˜์Œ ๊ธฐ๋ณธ๊ฐ’์€ -1)

private int sp = -1;

# push

public void push(Object o) {
    if(isFull(o)) {
        return;
    }
    
    stack[++sp] = o;
}

์Šคํƒ ํฌ์ธํ„ฐ๊ฐ€ ์ตœ๋Œ€ ํฌ๊ธฐ์™€ ๊ฐ™์œผ๋ฉด return

์•„๋‹ˆ๋ฉด ์Šคํƒ์˜ ์ตœ์ƒ์œ„ ์œ„์น˜์— ๊ฐ’์„ ๋„ฃ์Œ


# pop

public Object pop() {
    
    if(isEmpty(sp)) {
        return null;
    }
    
    Object o = stack[sp--];
    return o;
    
}

์Šคํƒ ํฌ์ธํ„ฐ๊ฐ€ 0์ด ๋˜๋ฉด null๋กœ return;

์•„๋‹ˆ๋ฉด ์Šคํƒ์˜ ์ตœ์ƒ์œ„ ์œ„์น˜ ๊ฐ’์„ ๊บผ๋‚ด์˜ด


# isEmpty

private boolean isEmpty(int cnt) {
    return sp == -1 ? true : false;
}

์ž…๋ ฅ ๊ฐ’์ด ์ตœ์ดˆ ๊ฐ’๊ณผ ๊ฐ™๋‹ค๋ฉด true, ์•„๋‹ˆ๋ฉด false


# isFull

private boolean isFull(int cnt) {
    return sp + 1 == MAX_SIZE ? true : false;
}

์Šคํƒ ํฌ์ธํ„ฐ ๊ฐ’+1์ด MAX_SIZE์™€ ๊ฐ™์œผ๋ฉด true, ์•„๋‹ˆ๋ฉด false



# ๋™์  ๋ฐฐ์—ด ์Šคํƒ

์œ„์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•˜๋ฉด ์Šคํƒ์—๋Š” MAX_SIZE๋ผ๋Š” ์ตœ๋Œ€ ํฌ๊ธฐ๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค

(์Šคํƒ ํฌ์ธํ„ฐ์™€ MAX_SIZE๋ฅผ ๋น„๊ตํ•ด์„œ isFull ๋ฉ”์†Œ๋“œ๋กœ ๋น„๊ตํ•ด์•ผ๋˜๊ธฐ ๋•Œ๋ฌธ!)


์ตœ๋Œ€ ํฌ๊ธฐ๊ฐ€ ์—†๋Š” ์Šคํƒ์„ ๋งŒ๋“œ๋ ค๋ฉด?

arraycopy๋ฅผ ํ™œ์šฉํ•œ ๋™์ ๋ฐฐ์—ด ์‚ฌ์šฉ


public void push(Object o) {
    
    if(isFull(sp)) {
        
        Object[] arr = new Object[MAX_SIZE * 2];
        System.arraycopy(stack, 0, arr, 0, MAX_SIZE);
        stack = arr;
        MAX_SIZE *= 2; // 2๋ฐฐ๋กœ ์ฆ๊ฐ€
    }
    
    stack[sp++] = o;
}

๊ธฐ์กด ์Šคํƒ์˜ 2๋ฐฐ ํฌ๊ธฐ๋งŒํผ ์ž„์‹œ ๋ฐฐ์—ด(arr)์„ ๋งŒ๋“ค๊ณ 

arraycopy๋ฅผ ํ†ตํ•ด stack์˜ ์ธ๋ฑ์Šค 0๋ถ€ํ„ฐ MAX_SIZE๋งŒํผ์„ arr ๋ฐฐ์—ด์˜ 0๋ฒˆ์งธ๋ถ€ํ„ฐ ๋ณต์‚ฌํ•œ๋‹ค

๋ณต์‚ฌ ํ›„์— arr์˜ ์ฐธ์กฐ๊ฐ’์„ stack์— ๋ฎ์–ด์”Œ์šด๋‹ค

๋งˆ์ง€๋ง‰์œผ๋กœ MAX_SIZE์˜ ๊ฐ’์„ 2๋ฐฐ๋กœ ์ฆ๊ฐ€์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค.


์ด๋Ÿฌ๋ฉด, ์Šคํƒ์ด ๊ฐ€๋“์ฐผ์„ ๋•Œ ์ž๋™์œผ๋กœ ํ™•์žฅ๋˜๋Š” ์Šคํƒ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ


# ์Šคํƒ์„ ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ•ด๋„ ํ•ด๊ฒฐ ๊ฐ€๋Šฅ

public class Node {

    public int data;
    public Node next;

    public Node() {
    }

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}
public class Stack {
    private Node head;
    private Node top;

    public Stack() {
        head = top = null;
    }

    private Node createNode(int data) {
        return new Node(data);
    }

    private boolean isEmpty() {
        return top == null ? true : false;
    }

    public void push(int data) {
        if (isEmpty()) { // ์Šคํƒ์ด ๋น„์–ด์žˆ๋‹ค๋ฉด
            head = createNode(data);
            top = head;
        }
        else { //์Šคํƒ์ด ๋น„์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด ๋งˆ์ง€๋ง‰ ์œ„์น˜๋ฅผ ์ฐพ์•„ ์ƒˆ ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐ์‹œํ‚จ๋‹ค.
            Node pointer = head;

            while (pointer.next != null)
                pointer = pointer.next;

            pointer.next = createNode(data);
            top = pointer.next;
        }
    }

    public int pop() {
        int popData;
        if (!isEmpty()) { // ์Šคํƒ์ด ๋น„์–ด์žˆ์ง€ ์•Š๋‹ค๋ฉด!! => ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด!!
            popData = top.data; // pop๋  ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ฐ›์•„๋†“๋Š”๋‹ค.
            Node pointer = head; // ํ˜„์žฌ ์œ„์น˜๋ฅผ ํ™•์ธํ•  ์ž„์‹œ ๋…ธ๋“œ ํฌ์ธํ„ฐ

            if (head == top) // ๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๋‚˜๋ผ๋ฉด
                head = top = null;
            else { // ๋ฐ์ดํ„ฐ๊ฐ€ 2๊ฐœ ์ด์ƒ์ด๋ผ๋ฉด
                while (pointer.next != top) // top์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋…ธ๋“œ๋ฅผ ์ฐพ๋Š”๋‹ค.
                    pointer = pointer.next;

                pointer.next = null; // ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ์˜ ์—ฐ๊ฒฐ์„ ๋Š๋Š”๋‹ค.
                top = pointer; // top์„ ์ด๋™์‹œํ‚จ๋‹ค.
            }
            return popData;
        }
        return -1; // -1์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋Š” ์˜๋ฏธ๋กœ ์ง€์ •ํ•ด๋‘ .

    }

}



# ํ(Queue)

์ž…๋ ฅ๊ณผ ์ถœ๋ ฅ์„ ํ•œ ์ชฝ ๋(front, rear)์œผ๋กœ ์ œํ•œ

# FIFO (First In First Out, ์„ ์ž…์„ ์ถœ) : ๊ฐ€์žฅ ๋จผ์ € ๋“ค์–ด์˜จ ๊ฒƒ์ด ๊ฐ€์žฅ ๋จผ์ € ๋‚˜์˜ด

์–ธ์ œ ์‚ฌ์šฉ?

๋ฒ„ํผ, ๋งˆ๊ตฌ ์ž…๋ ฅ๋œ ๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ๋ชปํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ, BFS


ํ์˜ ๊ฐ€์žฅ ์ฒซ ์›์†Œ๋ฅผ front, ๋ ์›์†Œ๋ฅผ rear๋ผ๊ณ  ๋ถ€๋ฆ„

ํ๋Š” ๋“ค์–ด์˜ฌ ๋•Œ rear๋กœ ๋“ค์–ด์˜ค์ง€๋งŒ, ๋‚˜์˜ฌ ๋•Œ๋Š” front๋ถ€ํ„ฐ ๋น ์ง€๋Š” ํŠน์„ฑ์„ ๊ฐ€์ง

์ ‘๊ทผ๋ฐฉ๋ฒ•์€ ๊ฐ€์žฅ ์ฒซ ์›์†Œ์™€ ๋ ์›์†Œ๋กœ๋งŒ ๊ฐ€๋Šฅ


๋ฐ์ดํ„ฐ ๋„ฃ์Œ : enQueue()

๋ฐ์ดํ„ฐ ๋บŒ : deQueue()

๋น„์–ด์žˆ๋Š” ์ง€ ํ™•์ธ : isEmpty()

๊ฝ‰์ฐจ์žˆ๋Š” ์ง€ ํ™•์ธ : isFull()


๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๊ณ  ๋บ„ ๋•Œ ํ•ด๋‹น ๊ฐ’์˜ ์œ„์น˜๋ฅผ ๊ธฐ์–ตํ•ด์•ผ ํ•จ. (์Šคํƒ์—์„œ ์Šคํƒ ํฌ์ธํ„ฐ์™€ ๊ฐ™์€ ์—ญํ• )

์ด ์œ„์น˜๋ฅผ ๊ธฐ์–ตํ•˜๊ณ  ์žˆ๋Š” ๊ฒŒ front์™€ rear

front : deQueue ํ•  ์œ„์น˜ ๊ธฐ์–ต

rear : enQueue ํ•  ์œ„์น˜ ๊ธฐ์–ต


# ๊ธฐ๋ณธ๊ฐ’

private int size = 0; 
private int rear = -1; 
private int front = -1;

Queue(int size) { 
    this.size = size;
    this.queue = new Object[size];
}


# enQueue

public void enQueue(Object o) {
    
    if(isFull()) {
        return;
    }
    
    queue[++rear] = o;
}

enQueue ์‹œ, ๊ฐ€๋“ ์ฐผ๋‹ค๋ฉด ๊ฝ‰ ์ฐจ ์žˆ๋Š” ์ƒํƒœ์—์„œ enQueue๋ฅผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— overflow

์•„๋‹ˆ๋ฉด rear์— ๊ฐ’ ๋„ฃ๊ณ  1 ์ฆ๊ฐ€



# deQueue

public Object deQueue(Object o) {
    
    if(isEmpty()) { 
        return null;
    }
    
    Object o = queue[front];
    queue[front++] = null;
    return o;
}

deQueue๋ฅผ ํ•  ๋•Œ ๊ณต๋ฐฑ์ด๋ฉด underflow

front์— ์œ„์น˜ํ•œ ๊ฐ’์„ object์— ๊บผ๋‚ธ ํ›„, ๊บผ๋‚ธ ์œ„์น˜๋Š” null๋กœ ์ฑ„์›Œ์คŒ


# isEmpty

public boolean isEmpty() {
    return front == rear;
}

front์™€ rear๊ฐ€ ๊ฐ™์•„์ง€๋ฉด ๋น„์–ด์ง„ ๊ฒƒ


# isFull

public boolean isFull() {
    return (rear == queueSize-1);
}

rear๊ฐ€ ์‚ฌ์ด์ฆˆ-1๊ณผ ๊ฐ™์•„์ง€๋ฉด ๊ฐ€๋“์ฐฌ ๊ฒƒ



์ผ๋ฐ˜ ํ์˜ ๋‹จ์  : ํ์— ๋นˆ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋‚จ์•„ ์žˆ์–ด๋„, ๊ฝ‰ ์ฐจ์žˆ๋Š”๊ฒƒ์œผ๋กœ ํŒ๋‹จํ•  ์ˆ˜๋„ ์žˆ์Œ

(rear๊ฐ€ ๋์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ)


์ด๋ฅผ ๊ฐœ์„ ํ•œ ๊ฒƒ์ด '์›ํ˜• ํ'

๋…ผ๋ฆฌ์ ์œผ๋กœ ๋ฐฐ์—ด์˜ ์ฒ˜์Œ๊ณผ ๋์ด ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•จ!


์›ํ˜• ํ๋Š” ์ดˆ๊ธฐ ๊ณต๋ฐฑ ์ƒํƒœ์ผ ๋•Œ front์™€ rear๊ฐ€ 0

๊ณต๋ฐฑ, ํฌํ™” ์ƒํƒœ๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด ์ž๋ฆฌ ํ•˜๋‚˜๋ฅผ ํ•ญ์ƒ ๋น„์›Œ๋‘ 

(index + 1) % size๋กœ ์ˆœํ™˜์‹œํ‚จ๋‹ค

# ๊ธฐ๋ณธ๊ฐ’

private int size = 0; 
private int rear = 0; 
private int front = 0;

Queue(int size) { 
    this.size = size;
    this.queue = new Object[size];
}

# enQueue

public void enQueue(Object o) {
    
    if(isFull()) {
        return;
    }
    
    rear = (++rear) % size;
    queue[rear] = o;
}

enQueue ์‹œ, ๊ฐ€๋“ ์ฐผ๋‹ค๋ฉด ๊ฝ‰ ์ฐจ ์žˆ๋Š” ์ƒํƒœ์—์„œ enQueue๋ฅผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— overflow



# deQueue

public Object deQueue(Object o) {
    
    if(isEmpty()) { 
        return null;
    }
    
    preIndex = front;
    front = (++front) % size;
    Object o = queue[preIndex];
    return o;
}

deQueue๋ฅผ ํ•  ๋•Œ ๊ณต๋ฐฑ์ด๋ฉด underflow


# isEmpty

public boolean isEmpty() {
    return front == rear;
}

front์™€ rear๊ฐ€ ๊ฐ™์•„์ง€๋ฉด ๋น„์–ด์ง„ ๊ฒƒ


# isFull

public boolean isFull() {
    return ((rear+1) % size == front);
}

rear+1%size๊ฐ€ front์™€ ๊ฐ™์œผ๋ฉด ๊ฐ€๋“์ฐฌ ๊ฒƒ


์›ํ˜• ํ์˜ ๋‹จ์  : ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์€ ์ž˜ ํ™œ์šฉํ•˜์ง€๋งŒ, ๋ฐฐ์—ด๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ์˜ ํฌ๊ธฐ๊ฐ€ ์ œํ•œ



์ด๋ฅผ ๊ฐœ์„ ํ•œ ๊ฒƒ์ด '์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ํ'

# ์—ฐ๊ฒฐ๋ฆฌ์ŠคํŠธ ํ๋Š” ํฌ๊ธฐ๊ฐ€ ์ œํ•œ์ด ์—†๊ณ  ์‚ฝ์ž…, ์‚ญ์ œ๊ฐ€ ํŽธ๋ฆฌ


# enqueue ๊ตฌํ˜„

public void enqueue(E item) {
    Node oldlast = tail; // ๊ธฐ์กด์˜ tail ์ž„์‹œ ์ €์žฅ
    tail = new Node; // ์ƒˆ๋กœ์šด tail ์ƒ์„ฑ
    tail.item = item;
    tail.next = null;
    if(isEmpty()) head = tail; // ํ๊ฐ€ ๋น„์–ด์žˆ์œผ๋ฉด head์™€ tail ๋ชจ๋‘ ๊ฐ™์€ ๋…ธ๋“œ ๊ฐ€๋ฆฌํ‚ด
    else oldlast.next = tail; // ๋น„์–ด์žˆ์ง€ ์•Š์œผ๋ฉด ๊ธฐ์กด tail์˜ next = ์ƒˆ๋กœ์šด tail๋กœ ์„ค์ •
}
  • ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€๋Š” ๋ ๋ถ€๋ถ„์ธ tail์— ํ•œ๋‹ค.

  • ๊ธฐ์กด์˜ tail๋Š” ๋ณด๊ด€ํ•˜๊ณ , ์ƒˆ๋กœ์šด tail ์ƒ์„ฑ

  • ํ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด head = tail๋ฅผ ํ†ตํ•ด ๋‘˜์ด ๊ฐ™์€ ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ํ•œ๋‹ค.

  • ํ๊ฐ€ ๋น„์–ด์žˆ์ง€ ์•Š์œผ๋ฉด, ๊ธฐ์กด tail์˜ next์— ์ƒˆ๋กœ๋งŒ๋“  tail๋ฅผ ์„ค์ •ํ•ด์ค€๋‹ค.


# dequeue ๊ตฌํ˜„

public T dequeue() {
    // ๋น„์–ด์žˆ์œผ๋ฉด
    if(isEmpty()) {
        tail = head;
        return null;
    }
    // ๋น„์–ด์žˆ์ง€ ์•Š์œผ๋ฉด
    else {
        T item = head.item; // ๋นผ๋‚ผ ํ˜„์žฌ front ๊ฐ’ ์ €์žฅ
        head = head.next; // front๋ฅผ ๋‹ค์Œ ๋…ธ๋“œ๋กœ ์„ค์ •
        return item;
    }
}
  • ๋ฐ์ดํ„ฐ๋Š” head๋กœ๋ถ€ํ„ฐ ๊บผ๋‚ธ๋‹ค. (๊ฐ€์žฅ ๋จผ์ € ๋“ค์–ด์˜จ ๊ฒƒ๋ถ€ํ„ฐ ๋นผ์•ผํ•˜๋ฏ€๋กœ)
  • head์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์ €์žฅํ•ด๋‘”๋‹ค.
  • ๊ธฐ์กด์˜ head๋ฅผ ๊ทธ ๋‹ค์Œ ๋…ธ๋“œ์˜ head๋กœ ์„ค์ •ํ•œ๋‹ค.
  • ์ €์žฅํ•ด๋‘” ๋ฐ์ดํ„ฐ๋ฅผ return ํ•ด์„œ ๊ฐ’์„ ๋นผ์˜จ๋‹ค.

์ด์ฒ˜๋Ÿผ ์‚ฝ์ž…์€ tail, ์ œ๊ฑฐ๋Š” head๋กœ ํ•˜๋ฉด์„œ ์‚ฝ์ž…/์‚ญ์ œ๋ฅผ ์Šคํƒ์ฒ˜๋Ÿผ O(1)์— ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์ตœ์ข… ์ˆ˜์ • : 12/17/2022, 7:23:59 AM