[C++] スタックとキュー


説明する

スタックとキューはコンピュータ サイエンスにおいて非常に重要なデータ構造であり、コンパイラ、オペレーティング システム、ネットワーク ルーターなどの多くのアプリケーションで使用されています。この記事では、スタックとキューの基本概念、操作、およびアプリケーションについて説明します。

1. スタックの概念と動作 スタックは後入れ先出し(LIFO)のデータ構造であり、基本的な動作にはプッシュとポップがあります。スタックの最上位要素は最後にプッシュされた要素であるため、ポップされる最初の要素になります。スタックは通常、配列またはリンク リストを使用して実装されます。

以下にいくつかの基本的なスタック操作を示します。
Push(item): 要素 item をスタックの先頭にプッシュします。
Pop(): スタックの最上位要素をポップして返します。
top(): スタックの最上位要素をポップせずに返します。
isEmpty(): スタックが空かどうかを確認します。
isFull(): スタックがいっぱいかどうかを確認します (配列実装の場合のみ)。

第 2 に、キューの概念と操作です。キューは先入れ先出し (FIFO) データ構造であり、その基本操作にはエンキューとデキューが含まれます。キューの末尾はキューに入れられた最後の要素であるため、キューから取り出される最初の要素になります。キューは通常、配列またはリンク リストを使用して実装されます。

以下にいくつかの基本的なキュー操作を示します。
enqueue(item): 要素 item をキューの末尾に挿入します。
dequeue(): キューの先頭から要素をポップして返します。
front(): キューの先頭にある要素を返しますが、ポップはしません。
isEmpty(): キューが空かどうかを確認します。
isFull(): キューがいっぱいかどうかを確認します (配列実装の場合のみ)。

1.スタック

共通インターフェース

ここに画像の説明を挿入

シミュレーションの実装

namespace tzc
{
    
    
	//适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结),
	//该种模式是将一个类的接口转换成客户希望的另外一个接口。
	//deque双端队列 优点是首尾端操作方便,一般用作栈和队列的容器适配器
	//容器适配器  
	template<class T, class Container= deque<T>>
	class stack
	{
    
    
	public:
		void push(const T& x)
		{
    
    
			_con.push_back(x);
		}
		void pop()
		{
    
    
			_con.pop_back();
		}

		T& top()
		{
    
    
			return _con.back();
		}

		size_t size()
		{
    
    
			return _con.size();
		}
		bool empty()
		{
    
    
			return _con.empty();
		}
	private:
		Container _con;
	};
	
	//测试
	void test_stack1()
	{
    
    
		//数组栈
		stack<int, vector<int>> st1;
		//链式栈
		stack<int, list<int>> st2;

		st1.push(1);
		st1.push(2);
		st1.push(3);
		st1.push(4);

		while (!st1.empty())
		{
    
    
			cout << st1.top() << " ";
			st1.pop();
		}
		cout << endl;

		st2.push(1);
		st2.push(2);
		st2.push(3);
		st2.push(4);

		while (!st2.empty())
		{
    
    
			cout << st2.top() << " ";
			st2.pop();
		}
		cout << endl;
	}
}

2、列に並ぶ

共通インターフェース

ここに画像の説明を挿入

シミュレーションの実装

namespace tzc
{
    
    
	//容器适配器
	template<class T, class Container= deque<T>>
	class queue
	{
    
    
	public:
		void push(const T& x)
		{
    
    
			_con.push_back(x);
		}
		void pop()
		{
    
    
			_con.pop_front();
			//_con.erase(_con.begin());
		}

		T& front()
		{
    
    
			return _con.front();
		}

		size_t size()
		{
    
    
			return _con.size();
		}
		bool empty()
		{
    
    
			return _con.empty();
		}


	private:
		Container _con;
	};

	void test_queue1()
	{
    
    
		queue<int, list<int>> q;

		q.push(1);
		q.push(2);
		q.push(3);
		q.push(4);

		while (!q.empty())
		{
    
    
			cout << q.front() << " ";
			q.pop();
		}
		cout << endl;
	}
}

3. OJ の質問を積み重ねてキューに入れる

①最小スタック数
ここに画像の説明を挿入

ほどく

class MinStack {
    
    
public:
    MinStack() {
    
    
    }
    //如果最小栈中没有元素或者比最小栈中元素还要小,就入栈
    void push(int val) {
    
    
        if (minst.empty() || minst.top() >= val)
        {
    
    
            minst.push(val);
        }
        st.push(val);
    }
    //如果要出栈的元素比最小栈中的元素还要小,最小栈中元素也需出栈
    void pop() {
    
    
        if (st.top() == minst.top())
        {
    
    
            minst.pop();
        }
        st.pop();
    }

    int top() {
    
    
        return st.top();
    }

    //最小栈中栈顶的元素就是最小元素
    int getMin() {
    
    
        return minst.top();
    }
private:
    stack<int> st;
    stack<int> minst;
};

②スタックプッシュ、ポップシーケンス

ここに画像の説明を挿入

ほどく

class Solution {
    
    
public:
    bool IsPopOrder(vector<int>& pushV, vector<int>& popV) {
    
    
        // write code here
        stack<int> st;
        int pushIndex=0,popIndex=0;
        while(pushIndex<pushV.size())
        {
    
    
            st.push(pushV[pushIndex++]);
            while(!st.empty()&&popV[popIndex]==st.top())
            {
    
    
                st.pop();
                popIndex++;
            }
        }
        return st.empty();
    }
};

おすすめ

転載: blog.csdn.net/Tianzhenchuan/article/details/131815499