栈和队列的互相实现

来源:互联网 发布:软件设计方案评审 编辑:程序博客网 时间:2024/06/07 14:42

栈:先进后出,栈与调归密切相关;
队列:先进先出,队列在图(包括树)的宽度优先遍历中需要用到。

用两个栈实现一个队列:

我们通过一个具体的例子来分析往该队列插入和删除元素的过程通过一个具体的例子来分析的方式通常能使问题变得很明朗,思路变得清晰。会在很大程度上简化问题。首先插入一个元素a,不妨先把它插入到stack1,此时stack1中的元素有{a},stack2 为空。再压入两个元素b 和c,还是插入到stack1中,此时stack1中的元素有{a,b, c} ,其中c 位于栈顶,而stack2仍然是空的。这个时候我们试着从队列中删除一个元素。按照队列先入先出的规则,由于a 比b、c 先插入到队列中,最先被删除的元素应该是a。元素a 存储在stack1中,但并不在栈顶上,因此不能直接进行删除。注意到stack2我们还一直没有使用过,现在是让stack2发挥作用的时候了。如果我们把stack1中的元素逐个弹出并压入stack2, 元素在stack2中的顺序正好和原来在stack1中的顺序相反。因此经过3 次弹出stack1和压入stack2操作之后,stack1 为空, 而stack2中的元素是{c,b,a} ,这个时候就可以弹出stack2的栈顶a 了。此时的stack1为空,而stack2 的元素为{c,b},其中b 在栈顶。如果我们还想继续删除队列的头部应该怎么办呢?剩下的两个元素是b 和c。b 比c 早进入队列,因此b 应该先删除。而此时b 恰好又在栈顶,因此直接弹出stack2的栈顶元素即可。这次弹出操作之后,stack1中仍然为空,而stack2为{c} 。从上面的分析中我们可以总结出删除一个元素的步骤: 
(1)当stack2 中不为空时, 在stack2中的栈顶元素是最先进入队列的元素, 可以弹出。
(2)如果stack2为空时,我们把stack1中的元素逐个弹出并压入stack2。
由于先进入队列的元素被压到stack1的底端,经过弹出和压入之后就处于stack2的顶端了, 又可以直接弹出。接下来再插入一个元素d。我们还是把它压入stack1 ,这样会不会有问题呢?我们考虑下一次删除队列的头部stack2不为空,直接弹出它的技顶元素c 。而c 的确是比d 先进入队列, 应该在d 之前从队列中删除, 因此不会出现任何矛盾。
template <typename T>class CQueue{public:CQueue(void);~CQueue(void);void AppendTail(T);T DeleteHead();private:stack<T> stack1;stack<T> stack2;};template <typename T> CQueue<T>::CQueue(void){}template <typename T> CQueue<T>::~CQueue(void){}template<typename T> void CQueue<T>::AppendTail(T element){stack1.push(element);}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 std::exception("queue is empty");T head=stack2.top();stack2.pop();return head;}int _tmain(int argc, _TCHAR* argv[]){CQueue<char> queue;    queue.AppendTail('a');    queue.AppendTail('b');    queue.AppendTail('c');    char head = queue.DeleteHead();    system("pause");    return 0;}
注意模板类的使用方式。一定要掌握通过具体的例子来分析问题的能力

用两个队列实现一个栈

我们通过一系列栈的压入和弹出操作来分析用两个队列模拟一个栈的过程。我们先往栈内压一个元素a。由于两个队列现在都是空的,我们可以选择把a 插入两个队列的任意一个。我们不妨把a插入queue1。接下来继续往内压入b 、c 两个元素,我们把它们都插入queue1。这个时候queue1包含3 个元素a 、b 和c,其中a 位于队列的头部,c 位于队列的尾部。现在我们考虑从内弹出一个元素。根据的后入先出原则,最后被压入战的c 应该最先被弹出。由于c 位于queue1的尾部,而我们每次只能从队列的头部删除元素,因此我们可以先从queue1中依次删除元素a、b并插入到queue2 中,再从queue1中删除元素c。这就相当于从中弹出元素c 了。我们可以用同样的方法从栈内弹出元素b 。接下来我们考虑往内压入一个元素d。此时queue1已经有一个元素,我们就把d 插入到queue1的尾部。如果我们再从内弹出一个元素,此时被弹出的应该是最后被压入的d。由于d 位于queue1的尾部,我们只能先从头删除queue1的元素井插入到queue2,直到在queue1中遇到d 再直接把它删除。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 留服认证不了怎么办 无公害认证书怎么办 假学历认证报告怎么办 留学要求寄原件怎么办 干部小三怀孕怎么办? 小三的孩子怎么办 把小三打住院了怎么办 小月子没人伺候怎么办 寝室室友有狐臭怎么办 室友在寝室养猫怎么办 和直接领导不合怎么办 房产共有人去世怎么办 发现邪教宣传内容怎么办 说课时两个课时怎么办 投稿文章被拒绝怎么办 中立性细胞偏低怎么办? 孩子爱告状老师怎么办 高中学不好数学怎么办 想做老师应该怎么办 教师职称换学校怎么办 大四差选修学分怎么办 尔雅通识课学分没修满怎么办 大学全英文授课怎么办 小孩脑部有囊肿怎么办 防震期间门应该怎么办 在家待着没意思怎么办 人户分离上学怎么办 小孩上学没人接送怎么办 宝宝上学没人接送怎么办 上海浦东新区酒类许可证怎么办 金税盘里报税处理打不开怎么办 惠民卡到期了怎么办 遇到不拴狗链的主人怎么办 平安福没钱续保怎么办 提前很久到机场怎么办 机场来早了怎么办 机场去早了怎么办 只有高中学历该怎么办 没钱没学历该怎么办 中招分数压线怎么办 两岁宝宝蛀牙怎么办