剑指offer面试题9——用两个栈实现队列

题目:用两个栈实现队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队尾插入节点和在队列头部删除节点的功能。

template<typename T>class CQueue 
{
public:
	CQueue(void);
	~CQueue(void);

	void appendTail(const T&node);
	T deleteHead();
private:
	stack<T>stack1;
	stack<T>stack2;

};

思路:

        队列是先进先出,栈是先进后出。这题题目给出了两个栈,首先假设我们往一个栈里面压入了三个元素a、b、c。作为一个队列,如果我们压入了a、b、c,那么先出的会是a。但是栈弹出的会是c,那么该怎么输出a呢,这里注意到我们利用了一个栈,还有一个栈没有使用,如果我们把第一个栈里面的元素依次压入第二个栈里面,那么第二个栈里面从上到下会是c、b、a,只要把第二个栈的首元素弹出去就可以。再来看看插入操作,插入的时候直接把元素压入第一个栈,输出的时候将元素取出并且压入第二个栈再进行出栈操作即可。

代码:

template<typename T> void CQueue<T>::appendTail(const T&node)
{
	stack1.push(node);
}

template<typename T> T CQueue<T>::deleteHead()
{
	if (stack2.size() <= 0)
	{
		while (stack1.size()>0)
		{
			T &data = stack1.top();
			stack1.pop();
			stack2.push(data);
		}
	}
	if (stack2.size() == 0)
		throw new exception("queue is empty");

	T head = stack2.top();
	stack2.pop();
	return head;
	
}

这道题还要学会怎么在类的外面定义函数。template<typename T>  函数类型 CQueue<T>::appendTail(const T&node)

复习:

         要注意的是,在复制数据的时候用引用可以节省时间,在往stack2复制数据结束之后,要判断队列里面是否还有元素。还要注意怎么定义模板类里面的函数。

二刷代码:

template<typename T>class CQueue
{
public:
	CQueue(void);
	~CQueue(void);

	void appendTail(const T&node);
	T deleteHead();
private:
	stack<T>stack1;
	stack<T>stack2;

};


template<typename T> void CQueue<T>::appendTail(const T&node)
{
	stack1.push(node);
}


template<typename T> T CQueue<T>::deleteHead()
{
	if (stack2.size() <= 0)
	{
		while (stack1.size()>0)
		{
			T &data = stack1.top();//用引用可以节省时间
			stack2.push(data);
			stack1.pop();
		}
		T head = stack2.top;
		stack2.pop();
	}

	if(stack2.size()==0)//判断队列是否已经没有元素
		throw new exception("queue is empty")
	
	T head = stack2.top();
	stack2.pop;
	
	return head;
}

镜像问题:用两个队列实现一个栈

思路:

      下面图表示两个队列,当向栈中压入a、b、c三个数之后,我们要弹出c,这个时候需要将a,b出队列queue1并且入队到queue2中,再删除c,弹出b的过程同理。压入d的时候直接入队到a后面就好了。

代码:

template<typename T>class CStack
{
public:
	CStack(void);
	~CStack(void);

	void appendTail(const T&node);
	T deleteHead();
private:
	queue<T>queue1;
	queue<T>queue2;

};

template<typename T> void CStack<T>::appendTail(const T&node)
{
	if (queue1.size() != 0) queue1.push(node);
	else queue2.push(node);
}

template<typename T> T CStack<T>::deleteHead()
{
	if (queue1.size() != 0)
	{
		while (queue1.size()!=1)
		{
			T temp = queue1.front();
			queue1.pop();
			queue2.push(temp);
		}
		queue1.pop();
		return temp;
	}
	else if (queue2.size() != 0)
	{
		while (queue2.size() != 1)
		{
			T temp = queue2.front();
			queue2.pop();
			queue1.push(temp);
		}
		queue2.pop();
		return temp;
	}
	else  throw new exception("stack is empty");


}
//这个代码是自己写的,也不知道对不对,欢迎谈论

复习:

思路还是差不多的,就是还有注意对栈为空的情况的判断。

二刷代码:

template<typename T>class CQueue
{
public:
	CQueue(void);
	~CQueue(void);

	void appendTail(const T&node);
	T deleteHead();
private:
	stack<T>stack1;
	stack<T>stack2;

};


template<typename T>class CStack
{
public:
	CStack(void);
	~CStack(void);

	void appendTail(const T&node);
	T deleteHead();
private:
	queue<T>queue1;
	queue<T>queue2;

};

template<typename T> void CStack<T>::appendTail(const T&node)
{
	if (queue1.size() != 0) queue1.push(node);
	else queue2.push(node);
}

template<typename T> T CStack<T>::deleteHead()
{
	if (queue1.size() != 0)
	{
		while (queue1.size()>1)
		{
			T node = queue1.front();
			queue1.pop();
			queue2.push(node);
		}

		T head = queue1.front();
		queue1.pop();

	}
	else if(queue2.size()>1){
		while (queue2.size() > 1)
		{
			T node = queue1.front();
			queue2.pop();
			queue1.push(node);
		}

		T head = queue2.front();
		queue2.pop();
	}
	else throw new exception("stack is empty");

	return head;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值