数据结构--栈和队列

 

好久不见,今天要跟大家介绍的另外两种非常重要的数据结构--栈和队列,为什么会把它们两个放在一起说呢,栈和队列虽然是特点针锋相对的两个数据结构,但是有意思的是它们却相互联系,比如我们可以用两个栈实现队列操作,用两个队列实现栈操作等,当然首先我们得了解它们的基础性质特点。

 

栈:

栈是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有其特殊含义,称为栈顶,相应的,表头端称为栈底。栈的特点是后进先出,即最后被压入栈的元素会第一个被弹出。

 

 

队列:

和栈相反,队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素,在队列中,允许插入的一端称为队尾,允许删除的一端称为队头。队列的特点是先进先出,即第一个进入队列的元素将会第一个出来。

 

 

用两个栈实现队列:

 

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

(题目来源:剑指 Offer 面试题 9 )

 

具体的代码怎么实现栈和队列这两种数据结构,这次我就不再详细用 C 展开,接下来我会直接调用 C++ 里面的 <stack>  <queue> 这两个库,如果有读者不知道这两种库的使用,建议百度一下基本操作,书写代码时会很方便整洁。

 

我们通过一个具体的例子来分析往该队列插入和删除元素的过程。首先插入一个元素 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 了。

 

从上面的分析中我们可以总结出删除一个元素的步骤:当 stack2 不为空时,在 stack2 中的栈顶元素是最先进入队列的元素,可以弹出。当 stack2 为空时,我们把 stack1 中的元素逐个弹出并压入 stack2 。由于先进入队列的元素被压倒 stack1 的低端,经过弹出和压入操作后就处于 stack2 的顶端,又可以直接弹出。

 

以上分析解释来自书上,但是就我个人看到这个题目时,第一想到的就是栈和队列的特点,一个先进后出,一个先进先出,既然要用两个栈来实现队列的效果,很明显,将数据进行入栈,出栈,再入栈,即可得到原本是队列形式的顺序了,而题解总结起来也就是如此,下面上模拟效果图。

 

 

上代码:

void appedTail(int n) // n 为入栈元素个数
{
   for(int i=0;i<n;i++){
       int t; cin>>t;
       stack1.push(t);
   }
}

void deleteHead(){
   if(stack2.size()<=0){ // 注意当 stack2 不为空时,不要压入其他元素进入 stack2 中
                           // 否则队列顺序会打乱。
       while(stack1.size()>0){
           int data = stack1.top();
           stack1.pop();
           stack2.push(data);
       }
   }

   if(stack2.size()==0){
       cout<<"queue is empty"<<endl;
       return ;
   }
   int head = stack2.top();
   stack2.pop();
   cout<<"delete head = "<<head<<" successful"<<endl;
}

好了,整个过程到这里就结束了,只要思路清晰,代码实现起来自然也就轻松许多,完整代码在微信公众号后台回复 [ 面试题9 ] 即可获得。

如果觉得文章还不错的话,还请大家点赞分享下。算是对「正经的码农」最大的支持!

同时欢迎大家关注微信公众号「正经的码农」更多好文章等着你。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值