mu_tou_man

导航

 

1.用两个栈来实现队列,栈是先进后出的,队列是先进先出的,这时,我们可以用stack1来专门入栈,stack2来专门出栈,具体地:

入队:直接入栈到stack1

出队:检测stack2是否为空,如果为空,则将stack1的所有元素移动到stack2中,

             再次判断stack2是否为空,如果为空抛出异常;

             如果非空,将stack2的栈顶元素出队。

代码如下:

#include <iostream>
#include <stack>
using namespace std;
//用两个栈实现一个队列stack1专门用来入队  stack2专门用来出队
template<class T>class Queue
{
public:
    Queue(void){};
    ~Queue(void){};
    void AppendTail(const T &ele);
    T DeleHead();
private:
    stack<T>stack1;
    stack<T>stack2;

};

//stack1专门用来入栈
template<class T> void Queue<T>::AppendTail(const T &ele)
{
    stack1.push(ele);
}
//stack2作为临时缓冲,将stack1入栈的元素逆序 然后出栈即可实现先入先出
template<class T> T Queue<T>::DeleHead()
{
    if (stack2.size()<=0)//stack2空 则将stack1的元素都放在stack2中
    {
        while (stack1.size()>0)
        {
            T node=stack1.top();
            stack2.push(node);
            stack1.pop();
        }
    }
    if (stack2.size()==0)//判断栈是否为空
    {
        cout<<"empty"<<endl;
        throw new exception();
    }
    T RetNode =stack2.top();//返回stack2的栈顶元素
    stack2.pop();//出栈
    return RetNode;
}

void main()
{
    Queue<int>*pQu=new Queue<int>();
    pQu->AppendTail(1);
    pQu->AppendTail(2);
    pQu->AppendTail(3);

    cout<<pQu->DeleHead()<<endl;
    pQu->AppendTail(4);
    pQu->AppendTail(5);
    cout<<pQu->DeleHead()<<endl;
    cout<<pQu->DeleHead()<<endl;
    cout<<pQu->DeleHead()<<endl;
    cout<<pQu->DeleHead()<<endl;
    cout<<pQu->DeleHead()<<endl;

}

 

  

 

 

 

 

 

队列是先进先出的,而栈是后进先出的,那么我们如何用两个队列实现栈的操作呢?

方法一:

      我们可以让queue1专门用来入栈和出栈操作,让queue2作为储存queue1的n-1个元素,也就是除了最后一个入队元素,然后将queue1中的最后元素出列,然后将queue2中的  n-1个元素放回queue1.

  思路

  q1是专职进出栈的,q2只是个中转站

  入栈时:直接入队列q1即可

  出栈时:把q1的除最后一个元素外全部转移到队q2中,然后把刚才剩下q1中的那个元素出队列。之后把q2中的全部元素转移回q1中。

  如下图所:

  

#include <queue>
#include <iostream>
using namespace std;
template <class T>
class Stack
{
public:
	Stack(){};
	~Stack(){};
	void StackPush(const T&data);
	T StackPop();
private:
	queue<T>que1;
	queue<T>que2;
};
//que1专门用来入栈
template<class T> void Stack<T>::StackPush(const T&data)
{
	que1.push(data);
}
//que2作为临时存储que1的多余变量,当出栈后要将所有元素还给que1
template<class T> T Stack<T>::StackPop()
{
	if (que1.size()<=0)
	{
		cout<<"empty"<<endl;
		throw new exception("empty");
	}
	else//que1的变量大于等于1个时
	{
		while(que1.size()>1)//将最先入n-1个元素的存que2中
		{
			que2.push(que1.front());
			que1.pop();
		}
		T RetData=que1.front();//返回最后入的元素
		que1.pop();
		while(que2.size()>0)//再将que2的元素存回que1
		{
			que1.push(que2.front());
			que2.pop();
		}
		return RetData;
	}
}

void main()
{
	Stack<int > *pSt=new Stack<int >();
	pSt->StackPush(1);
	pSt->StackPush(2);
	pSt->StackPush(3);
	cout<<pSt->StackPop()<<endl;
	cout<<pSt->StackPop()<<endl;
	cout<<pSt->StackPop()<<endl;
//	cout<<pSt->StackPop()<<endl;//抛异常
}

  结果如下图:

 

  然后我们发现,如果队列中元素较多时,每当移除一个元素,那么剩余的n-1个元素都要拷贝进queue2,然后再从queue2拷进queue1,这样增加了时间复杂度,那么能不能有其他更好的办法呢?

 

方法二:

 

  让两个栈都当做出栈或者入栈的队列,当入栈时候,先选定一个que1入栈,当出栈时候将que1的n-1个元素移动que2。那么下一次出栈的队列为que2,再将n-1个元素移动到que1,依次.....

  那么入栈时候该选择哪个呢?很显然,入栈也是来回变的,每当有一次出栈操作时,下次入栈时所选的队列都会改变,这时候我们只需要一个标志位flag来选定该入哪个队列就好了。

  代码如下:

#include <queue>
#include <iostream>
using namespace std;
template <class T>
class Stack
{
public:
    Stack(){};
    ~Stack(){};
    void StackPush(const T&data);
    T StackPop();
private:
    queue<T>que1;
    queue<T>que2;
    static bool flag;//用来标识该在哪个队列入栈的标识 
};


template<class T> bool Stack<T>::flag=true;//初始化为TRUE 在que1中入栈
template<class T> void Stack<T>::StackPush(const T&data)
{
    queue<T>*quTemp=NULL;//用于指向要入栈的队列,注意初始化格式
    if (flag)//标识用来决定该入栈到哪个队列
    {
        quTemp=&que1;
    }
    else 
    {
        quTemp=&que2;
    }
    quTemp->push(data);
}


template<class T> T Stack<T>::StackPop()
{
    flag=!flag;//将标识取反
    queue<T>*popTemp=NULL;//用于出栈的临时队列
    queue<T>*saveTemp=NULL;//用于保存n-1个多余变量的队列
    if (que1.size()>=1)
    {
        popTemp=&que1;
        saveTemp=&que2;
    }
    else
    {
        popTemp=&que2;
        saveTemp=&que1;
    }
    if (popTemp->size()<=0)
    {
        cout<<"Empty"<<endl;
        throw new exception("the stack is empty");
    }
    while(popTemp->size()>1)//出栈的队列中元素大于1个 移动到另一个队列中
    {
        saveTemp->push(popTemp->front());
        popTemp->pop();
    }
    T RetVal=popTemp->front();//返回最后一个元素
    popTemp->pop();
    return RetVal;
}


void main()
{
    Stack<int> *pSt=new Stack<int>();
    
    pSt->StackPush(1);
    pSt->StackPush(2);
    pSt->StackPush(3);
     cout<<pSt->StackPop()<<endl;
    cout<<pSt->StackPop()<<endl;

    pSt->StackPush(4);
    pSt->StackPush(5);    

    cout<<pSt->StackPop()<<endl;
    cout<<pSt->StackPop()<<endl;
    cout<<pSt->StackPop()<<endl;

}

运行结果如下图所示:

 

posted on 2014-09-03 16:35  mu_tou_man  阅读(249)  评论(0编辑  收藏  举报