【干货】容器适配器实现两个栈模拟队列

用两个栈模拟队列的思想就是“倒水思想”,这里我们用自定义类型模拟出线性表,再用线性表做容器实现栈的数据结构,最后用栈来实现队列,代码如下:

#include<iostream>
#include<string>
#include<cassert>
struct __TrueType//类型萃取
{
	bool Get()
	{
		return true;
	}
};
struct __FalseType
{
	bool Get()
	{
		return false;
	}
};

template <class _Tp>
struct TypeTraits
{
	typedef __FalseType   __IsPODType;
};

template <>
struct TypeTraits< bool>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< char>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned char >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< short>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned short >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< int>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned int >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< long>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned long >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< long long >
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< unsigned long long>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< float>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< double>
{
	typedef __TrueType     __IsPODType;
};

template <>
struct TypeTraits< long double >
{
	typedef __TrueType     __IsPODType;
};

template <class _Tp>
struct TypeTraits< _Tp*>
{
	typedef __TrueType     __IsPODType;
};

template <class T>//自定义类型实现线性表
class SeqList
{
public:
	SeqList()
		:_size(0),
		_capacity(10),
		_array(new T[_capacity])
	{
		memset(_array, 0, sizeof(T)*_capacity);
	}
	SeqList(const T &x)
		:_size(1),
		_capacity(10),
		_array(new T[_capacity])
	{
		_array[0] = x;
	}
	SeqList(const SeqList & x)
	{
		_array = new T[x._size];
		my_memcpy(_array, x._array, sizeof(T)*x._size);
		_capacity = x._size;
		_size = _capacity;
	}
	void PushBack(const T & x)
	{
		_CheckCapacity();
		_array[_size++] = x;
	}
	void PushFront(const T & x)
	{
		_CheckCapacity();
		for (size_t i = _size; i > 1; i--)
		{
			_array[_size] = _array[_size - 1];
		}
		_size++;
		_array[0] = x;
	}
	void PopBack()
	{
		_size--;
	}
	void PopFront()
	{
		assert(_size);
		for (size_t i = 0; i < _size - 1; i++)
		{
			_array[i] = _array[i + 1];
		}
		_size--;
	}
	size_t Size()
	{
		return _size;
	}
	SeqList & operator = (SeqList  l)
	{
		swap(_array, l._array);
		swap(_size, l._size);
		swap(_capacity, l._capacity);
		return *this;
	}

	~SeqList()
	{
		if (_array)
		{
			delete[] _array;
		}
	}
	T& operator [] (const size_t t)
	{
		return _array[t];
	}
private:
	void _CheckCapacity()
	{
		if (_size >= _capacity)
		{
			_capacity *= 3;
			T * tmp = new T[_capacity];
			memcpy(tmp, _array, sizeof(T)*_capacity);
			delete[] _array;
			_array = tmp;
		}
	}
	void my_memcpy(T* dst, const T* src, size_t size)
	{
		if (TypeTraits <T>::__IsPODType().Get())
		{
			memcpy(dst, src, size*sizeof (T));
		}
		else
		{
			for (size_t i = 0; i < size; ++i)
			{
				dst[i] = src[i];
			}
		}
	}
	size_t _size;
	size_t _capacity;
	T *_array;
};
template <class T,
	typename Contianer = SeqList<T> >//适配器实现栈
class Stack
{
public:
	void Push(const T & x)
	{
		_con.PushBack(x);
	}
	void Pop()
	{
		_con.PopBack();
	}
	size_t Size()
	{
		return _con.Size();
	}
	bool Empty()
	{
		return Size() == 0;
	}
	T&top()
	{
		return _con[Size() - 1];
	}
protected:
	Contianer _con;
};
template <class T,
	typename container = Stack<T> >//以栈为适配器,实现队列
class Queue
{
public:
	bool Empty()
	{
		return (_InStack.Empty() && _OutStack().Empty());
	}
	size_t Size()
	{
		return _InStack.Size() + _OutStack.Size();
	}
	void Push(const T &x)
	{
		_InStack.Push(x);
	}
	void Pop()
	{
		size_t MoveCount = _InStack.Size() - 1;
		for (size_t iCount = MoveCount; iCount > 0; --iCount)
		{
			T temp = _InStack.top();
			_OutStack.Push(temp);
			_InStack.Pop();
		}
		_InStack.Pop();
		while (false == _OutStack.Empty())
		{
			T temp = _OutStack.top();
			_InStack.Push(temp);
			_OutStack.Pop();
		}
	}
	T& Front()
	{
		return _InStack.top();
	}
	T& Back()
	{

		size_t MoveCount = _InStack.Size() - 1;
		for (size_t iCount = MoveCount; iCount > 0; --iCount)
		{
			T temp = _InStack.top();
			_OutStack.Push(temp);
			_InStack.Pop();
		}
		T ret = _InStack.top();
		while (false == _OutStack.Empty())
		{
			T temp = _OutStack.top();
			_Instack.Push(temp);
			_OutStack.Pop();
		}
		return ret;
	}
	void PrintQueue()
	{
		size_t MoveCount = _InStack.Size();
		for (size_t iCount = MoveCount; iCount > 0; --iCount)
		{
			T temp = _InStack.top();
			_OutStack.Push(temp);
			_InStack.Pop();
		}
		while (false == _OutStack.Empty())
		{
			T temp = _OutStack.top();
			_InStack.Push(temp);
			cout << "<-" << temp;
			_OutStack.Pop();
		}
		cout << endl;
	}
private:
	container _InStack;
	container _OutStack;
};

测试用例如下:

void Test()
{
	Queue<int> q1;
	q1.Push(1);
	q1.Push(2);
	q1.Push(3);
	q1.Push(4);
	q1.Push(5);
	q1.Push(6);
	q1.PrintQueue();
	q1.Pop();
	q1.PrintQueue();

}

如有什么不足或疑问,希望指教

时间: 2024-10-27 13:15:44

【干货】容器适配器实现两个栈模拟队列的相关文章

7 两个栈模拟队列,两个队列模拟栈

利用两个栈模拟队列 stack1,stack2 首先向stack1当中放入数据,如果需要输出数据,从stack2中delete数据,如果stack2为空,就把stack1中数据导入stack2 <span style="font-size:14px;">#include "static.h" #include <iostream> #include <stack> template<typename T> class

利用两个栈模拟队列

/************************************************** 题目:用两个栈模拟队列的基本操作1入队2,出队3判断队空4判断队满 s1做为输入栈的元素,一个个压栈相当于入队 s2作为输出队列的元素, 一个个出栈相当于出队 *************************************************/ #include <iostream> #include <cstdio> using namespace std; c

自定义栈的实现及使用两个栈模拟队列

一,使用单链表实现栈 ①栈需要一个栈顶指针 ②栈的基本操作有出栈和入栈,以及判断栈是否为空 ③单链表中每个结点表示一个栈元素,每个结点有指向下一个结点的指针.因此,在栈内部需要实现一个单链表.代码如下: public class Stack<T extends Comparable<? super T>>{ private class Node{ T ele; Node next; public Node(T ele) { this.ele = ele; } } Node top;

数据结构复习之用两个栈模拟队列操作

#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define MAXSIZE 100 using namespace std; struct Stack{ int s[MAXSIZE]; int top=0; bool stackOverFlow(){ if(top >= MAXSIZE) return true; return false; } bo

剑指offer系列5---两个栈 模拟队列的操作

[题目]两个栈 模拟队列的入队出队操作 1 package com.exe1.offer; 2 3 /** 4 * [题目 ]:用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 5 * 队列的出队:应该是队列的列首先出,即栈底元素先出:思路:先把stack1元素一个个弹至上stack2中,再顺序出stack2中数即为队列的出队顺序. 6 * 入队:先放到栈1中 7 * @author WGS 8 * 9 */ 10 import java.util.Stack

用两个栈模拟实现一个队列

题目:如何用两个栈模拟实现一个队列?  如果这两个堆栈的容量分别是m和n(m>n),你的方法能保证的队列容量是多少?(这里讨论的是顺序栈,如果是链式栈的话完全没有必要考虑空间) 分析:栈的特点是“后进先出(LIFO)”,而队列的特点是“先进先出(FIFO)”.用两个栈模拟实现一个队列的基本思路是:用一个栈作为存储空间,另一个栈作为输出缓冲区,把元素按顺序压入两栈(模拟的队列),并按此顺序出队并输出即可. 如下图,用容量为m的栈作为存储空间,容量为n的栈作为输出缓冲区,一开始先将n个元素压入(pu

web前端面试系列 - 数据结构(两个栈模拟一个队列)

一. 用两个栈模拟一个队列 思路一: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时将数据压人s1 3. 出队时将s1弹出,并压人s2,然后弹出s2中的顶部数据,最后再将剩余数据弹出s2,并压人s1. 思路二: 1. 一个栈s1作为数据存储,另一个栈s2,作为临时数据存储. 2. 入队时,判断s1, 是否为空,如果不为空,则将数据直接压入s1, 如果为空,则将s2中的数据全部倒入s1,在将数据压人s1. 3. 出队时,判断s2, 是否为空,如果不为空,则直接弹出s2

用两个栈模拟无限长队列

思路:设置两个栈,栈1起入队的作用.栈2起出队的作用.入队时,所有元素进栈1,栈满时会通过realloc函数追加存储空间并且保存原来栈1的元素.出队时,先判断栈2是否为空,若为空,则会判断栈1是否为空,栈1为空,则说明队列为空,栈1不为空则将栈1的元素全部出栈并入栈2,栈2满时依然通过realloc追加存储空间,然后栈2元素出栈;若栈2不为空,栈2元素直接出栈 extern void *realloc(void *mem_address, unsigned int newsize);功能:先释放

两个栈模拟一个队列和两个队列模拟一个栈

此为网易的一道笔试题.到时候秀逗,不知所云.后来研究之后记录下,以备以后经常翻阅. 栈:先进后出 push和pop 队列:先进先出 offer和poll (1)两个栈模拟一个队列 即将先进后出实现先进先出.比较容易理解,只要所有数据先往一个栈里push,然后将该栈中的数据依次pop出来再push进第二个队列,则顺序自然颠倒过来了,则每次pop是从第二个队列中取数据. import java.util.*; public class StackQueue{ private Stack<Intege