스택 및 큐의 상호 실현

1 스택 및 대기열

스택 : 선입 선출 데이터 구조
대기열 :
그림에 표시된 선입 선출 데이터 구조 :

여기에 사진 설명 삽입

그렇다면 C ++를 예로 들어 보겠습니다. 사용하는 프로그래밍 언어의 스택과 큐는 무엇입니까? 다음 측면에 대해 생각할 수 있습니다.

  1. C ++ 스택 은 컨테이너입니까?
  2. 우리가 사용하는 스택 어떤 STL 버전에 속합니까 ?
  3. 그것을 달성하기 위해 STL에서 스택 을 어떻게 사용 합니까?
  4. 스택스택 공간 을 순회하는 반복기를 제공 합니까?

C ++ 표준 라이브러리에는 여러 버전이 있습니다. 해당 스택 및 큐의 구현 원리를 알기 위해서는 사용중인 STL 버전을 알아야합니다. HP의 Silicon Graphics Computer Systems에서 참조하는 SGI STL을 사용합니다. STL 구현, Linux C ++ 컴파일러 GCC에 의해 채택 된 SGI STL은 오픈 소스 소프트웨어이며 소스 코드의 가독성이 높습니다.
스택에 대해 이야기합시다
여기에 사진 설명 삽입

  1. 스택은 푸시 및 팝과 같은 인터페이스를 제공합니다. 모든 요소는 선입 선출 규칙을 준수해야하므로 스택은 순회 기능을 제공하지 않으며 반복기를 제공하지도 않습니다. 세트 또는 맵과 달리 모든 요소를 ​​순회하는 반복기를 제공합니다.
  2. 스택은 모든 작업을 완료하기 위해 하단 컨테이너를 기반으로하여 외부에 통합 인터페이스를 제공하고 하단 컨테이너는 플러그 가능합니다. 스택의 기능을 구현하는 데 사용되는 컨테이너를 제어 할 수 있습니다. 따라서 STL의 스택은 컨테이너가 아니라 컨테이너 어댑터로 분류됩니다.

그렇다면 STL에서 스택을 구현하는 데 어떤 컨테이너가 사용됩니까?

아래 그림에서 볼 수 있듯이 스택의 내부 구조, 스택의 기본 구현은 벡터, deque, 목록이 모두 가능하며 주로 배열 및 연결 목록의 기본 구현이 가능합니다.
여기에 사진 설명 삽입
우리는 일반적으로 SGI STL을 사용합니다. 기본 구현이 지정되지 않았습니다. 기본값은 기본적으로 스택의 하위 수준 구조로 deque입니다. deque는 양방향 대기열로, 한 섹션이 봉인되어있는 한 다른 쪽 끝을 열어서 만 스택의 논리를 실현할 수 있습니다.

스택이 설명 된 후 대기열이 이해하기 더 쉽습니까?

큐의 선입 선출 데이터 구조도 순회 동작을 허용하지 않으며 반복자를 제공하지 않습니다. SGI STL의 큐는 deque를 기본 하단 구조로 사용합니다.
따라서 STL의 큐는 컨테이너가 아니라 컨테이너 어댑터로 분류됩니다.

3 스택을 사용하여 대기열 구현

여기에 사진 설명 삽입
https://leetcode-cn.com/problems/implement-queue-using-stacks/

3.1 사고 분석

스택을 사용하여 대기열의 동작을 모델링하면 스택을 하나만 사용하는 경우 확실히 작동하지 않으므로 두 개의 스택, 하나의 입력 스택 및 하나의 출력 스택이 필요합니다. 여기서는 입력 스택과 스택 간의 관계에주의해야합니다. 출력 스택.
다음은 거물 https://mp.weixin.qq.com/s/P6tupDwRFi6Ay-L7DT4NVg의 애니메이션을 인용합니다.

3.2 코드 구현

class MyQueue {
    
    
    //用两个栈实现队列
public:
    stack<int> stackIn;
    stack<int> stackOut;
    /** Initialize your data structure here. */
    MyQueue() {
    
    

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
    
    
        stackIn.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
    
    
       //当stackOut中是空的时候把stackIn中的数据导入到stackOut中
       if (stackOut.empty()) {
    
    
           //把stackIn中的数据导入,直到其为空为止
           while (!stackIn.empty()) {
    
    
               stackOut.push(stackIn.top());
               stackIn.pop();
           }
       }
       int result = stackOut.top();
       stackOut.pop();
       return result;
    }
    
    /** Get the front element. */
    int peek() {
    
    
        int ret = this->pop();
        stackOut.push(ret);
        return ret;
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
    
    
       return stackIn.empty() && stackOut.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

4 대기열을 사용하여 스택 구현

여기에 사진 설명 삽입
https://leetcode-cn.com/problems/implement-stack-using-queues/

4.1 사고 분석

위는 스택을 사용하여 대기열, 입력 스택 및 출력 스택을 구현하는 것입니다. 대기열을 사용하여 스택을 구현할 수 있습니까? 실제로 작동하지 않습니다. 대기열은 선입 선출을 따릅니다. 한 큐의 데이터를 다른 큐로 가져 오면 데이터의 순서가 변경되지 않고 선입 선출 (first-in-last-out) 순서가됩니다.
따라서 대기열을 사용하여 스택을 구현하는 아이디어는 두 개의 대기열과 하나의 대기열이 백업으로 사용되는 것입니다. 두 개의 대기열 que1 및 que2는 대기열의 기능을 구현하는 데 사용됩니다. que2는 실제로 백업 기능입니다. que1의 마지막 요소를 제외한 모든 요소는 que2로 백업 된 다음 마지막 요소가 팝되고 다른 요소는 que2에서 다시 가져옵니다. que1.
거인의 애니메이션 사진 인용 : https://mp.weixin.qq.com/s/yzn6ktUlL-vRG3-m5a8_Yw

4.2 코드 구현

class MyStack {
    
    
public:
    //用两个队列实现栈的功能----后进先出
    queue<int> que1;
    queue<int> que2;//用于临时备份数据
    /** Initialize your data structure here. */
    MyStack() {
    
    

    }
    
    /** Push element x onto stack. */
    void push(int x) {
    
    
        que1.push(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    
    
        //将que1中的数据放入到que2中,直到que1中只剩1个数据
        while (que1.size() > 1) {
    
    
            que2.push(que1.front());
            que1.pop();
        }
        //此时que1中有一个数据
        int ret = que1.front();
        que1.pop();
        //把que2中的数据放回que1中
        while(!que2.empty()) {
    
    
            que1.push(que2.front());
            que2.pop();
        }
        return ret;
    }
    
    /** Get the top element. */
    int top() {
    
    
        return que1.back();//back:队列尾   front:队列头
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
    
    
        return que1.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

추천

출처blog.csdn.net/CZHLNN/article/details/113849343