《算法(第四版)》1.4.27用栈表示队列,练习题学习小结

《算法(第四版)》1.4.27:两个栈实现的队列。

思路a:有两个栈s和st,s视为栈,st视为队列,st.push(s.pop())实现item排列顺序的变换。添加item时,item先进入栈s,再通过对应关系重置“队列”st;删除item时,item先从“队列”st弹出,再通过对应关系重置栈s。对s和st的重置需要用到栈的复制。

阅读了这篇博客后又有了如下总结https://blog.csdn.net/synapse7/article/details/18133787
思路b:思路a实际上用了四个栈,转换的时候对栈的遍历次数过多,栈s和st的利用率低。可以考虑联用栈s和栈st一起表示队列。将栈s视为队列的逆序,st作为缓冲区,入队时,item直接压入s;出队时,将s中的item逐个倒入st,完成后弹出st顶部的item,再将st的item倒回s。所以s和st非空即满。
思路c:思路b中栈s和栈st的联用效率低,有些“倒回”操作是多余的。如果连续进行出队操作,则无需将st倒回s。所以在入队操作前判断s是否为空,若为空,则将st倒回s;在出队操作前判断st是否为空,若为空,则将s倒入st。

思路d:考虑到st中的item总是s倒入的,假设在“倒出”操作完成后,直接往s中压入新的item,会发现st中的item重要先于s中的item入队,故在st完全为空后,可以再进行“倒出”操作。简言之,不论s是否为空,可以直接进行item压入。Java程序如下
在这里插入图片描述

public class QueueStack<Item> {

	private Stack<Item> s = new Stack<Item>();
	private Stack<Item> st = new Stack<Item>();
	
	public boolean isEmpty() {
		return st.isEmpty() && s.isEmpty();
	}
	public int size() {
		return st.size() + s.size();
	}

	public void enqueue(Item item) {
		//像表尾添加元素
		/***思路c
		if(s.isEmpty()) {  //非空即满
			while(!st.isEmpty()) {
				s.push(st.pop());
			}
			s.push(item);
		} else {
			s.push(item);
		}  **/
		s.push(item);
	}
	public Item dequeue() {
		//从表头删除元素
		if(st.isEmpty()) {  //非空即满
			while(!s.isEmpty()) {
				st.push(s.pop());
			} 
			return st.pop();
		} else {
			return st.pop();
		}
	}
	
}

《算法(第四版)》1.3.49:栈与队列。用有限个栈实现一个队列,保证每个队列(在最坏的情况下)都只需要常数次的栈操作。
用两个栈表示队列,最坏的情况下,时间复杂度为O(N),比如第一次压入k个数,再弹出时需要进行k次倒出操作。此题实现将另起一篇介绍。https://blog.csdn.net/MaaaMalik/article/details/94163051

《算法(第四版)》部分练习题索引

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值