背包、队列和栈

背包(Bag)、队列(Queue)、下压栈(Stuck)是基础数据类型集合的三种类型,他们的区别在于删除或者访问对象的顺序不同。


背包

背包是一种不支持从中删除元素的集合数据类型,它的作用就是帮助用例收集元素并迭代遍历所有收集到的元素。
具体实现:
/**
 * 背包
 * @author xiaoqi
 *
 * @param <Item>
 */
public class Bag<Item> {
	private Node node;
	
	private class Node{
		Item item;
		Node next;
	}
	
	//和Stuck的push一样
	public void add(Item item){
		Node oldFirst = node;
		node = new Node();
		node.item = item;
		node.next = oldFirst;
	}
	
}

队列

队列是一种基于先进先出策略的集合类型。就好比排队一样,先到的人,先结束工作出去。它们的入列顺序和出列顺序相同。
如下所示,它将队列表示为一条从最早插入的元素到最近插入元素的链表,first指向队列的开头,last指向队列的结尾。每将一个元素入列(enqueue),就将它加入到表尾;要将一个元素出列(dequeue),就要删除表头节点。
/**
 * 先进先出的队列
 * @author xiaoqi
 *
 * @param <Item>
 */
public class Queue<Item> {
	private Node first;//最早添加节点的链接
	private Node last;//最近添加的节点
	private int N;
	
	private class Node{
		Item item;
		Node next;
	}
	
	private boolean isEmpty(){
		return first==null;
	}
	
	private int size(){
		return N;
	}
	
	//加入队列
	public void enqueue(Item item){
		Node oldFirst = last;
		last = new Node();
		last.item = item;
		last.next = null;
		if(isEmpty()){
			first = last;
		}else{
			oldFirst.next = last;
		}
		N++;
	}
	
	//删除
	public Item dequeue(){
		if(isEmpty()){
			return null;
		}else{
			Item item = first.item;
			first = first.next;
			N--;
			return item;
		}
	}
}

下压栈是一种基于后进先出策略的集合类型,元素处理顺序和它们被压入的顺序刚好相反。就如同纸一样,我们一张一张放上去,当我们要拿出来的时候,肯定从最顶部开始拿,如果上面的没有被拿掉,下面的永远不会拿到。
例如 (1+(2+3)*5)
操作过程:
1、将操作数压入操作数栈
2、将运算符压入运算符栈
3、忽略左括号
4、遇到右括号,弹出一个运算符,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈。
实现栈的两种方式:

基于数组实现(ArrayList)

优点:1、每项操作的用时都和集合的大小无关
2、空间需求总是不超过集合大小乘以一个常数
/**
 * 栈 动态调整数组大小的实现
 * @author xiaoqi
 *
 * @param <Item>
 */
public class ResizingArrayStack<Item>{
	private Item[] a= (Item[]) new Object[1];//通过强转,让数组泛型
	private int N;//元素个数
	
	//通过元素个数判断栈是否为空
	public boolean isEmpty(){
		return N==0;
	}
	
	//返回栈中元素个数
	public int size(){
		return N;
	}
	
	//动态调整数组大小
	private void resize(int max){
		Item[] temp = (Item[]) new Object[max];
		//将所有数据复制到新的数组
		for(int i=0;i<N;i++){
			temp[i] = a[i];
		}
		//指向新的引用
		a = temp;
	}
	
	//添加元素到栈顶
	public void push(Item item){
		if(N == a.length){
			//当数组大小充满时,扩大数组大小为两倍
			resize(2*a.length);
		}
		a[N++] = item;
	}
	
	//从栈顶删除元素
	public Item pop(){
		Item item = a[--N];
		a[N] = null;//避免对象游离(无引用对象)
		if(N > 0 && N == a.length/4){
			//当数组大小为总长度4分之1时,调整数组大小为原长度一半
			resize(a.length/2);
		}
		return item;
	}
	
	public Iterator<Item> iterator(){
		return new ReverseArrayIterator();
	}
	
	private class ReverseArrayIterator implements Iterator<Item>{
		private int i=N;
		
		@Override
		public boolean hasNext() {
			return i > 0;
		}

		@Override
		public Item next() {
			return a[--i];
		}
		
	}

}

基于链表实现(LinkedList):

优点:1、所需空间总是和集合的大小成正比
   2、操作的时间总和集合的大小无关

/**
 * 栈 通过链表实现
 * @author xiaoqi
 *
 * @param <Item>
 */
public class Stack<Item> {
	private Node first;//栈顶元素(最近添加的元素)
	private int N;
	private class Node{
		Item item;
		Node next;
	}
	
	//通过元素个数判断栈是否为空
	public boolean isEmpty(){
		return first==null;
	}
	
	//返回栈中元素个数
	public int size(){
		return N;
	}
	
	//压入栈顶
	public void push(Item item){
		Node oldFirst = first;
		first = new Node();
		first.item = item;
		first.next = oldFirst;
		N++;
	}
	
	//删除栈顶元素
	public Item pop(){
		Item item = null;
		if(!isEmpty()){
			item = first.item;
			first = first.next;
			N--;
		}
		return item;
	}
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值