java标准库中使用的栈和队列

java标准库中使用的栈

Stack的入栈和出栈的操作:

①把元素压栈:push(E);

②把栈顶的元素“弹出”:pop(E);

③取栈顶元素但不弹出:peek(E)

package java.util;

public class Stack<E> extends Vector<E> {
    public Stack() {}

	//入栈
    public E push(E item) {
        addElement(item);
        return item;
    }
    
    //出栈
    public synchronized E pop() {
        E       obj;
        int     len = size();
        obj = peek();
        removeElementAt(len - 1);
        return obj;
    }
	// 返回栈顶元素
    public synchronized E peek() {
        int     len = size();
        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }
}

java标准库中使用的队列

package java.util;
public interface Queue<E> extends Collection<E> {
    // add()和offer()都是向队列中添加一个元素。一些队列有大小限制,因此如果想在一个满的队列中加入一个新项,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。因此就可以在程序中进行有效的判断!
	// 入队列
    boolean add(E e);
	// 入队列
    boolean offer(E e);
	
    // remove() 和 poll() 方法都是从队列中删除第一个元素。如果队列元素为空,调用remove() 的行为与 Collection 接口的版本相似会抛出异常,但是新的 poll() 方法在用空集合调用时只是返回 null。因此新的方法更适合容易出现异常条件的情况。
    // 出队列
    E remove();
    // 出队列
    E poll();

    // element() 和 peek() 用于在队列的头部查询元素。与 remove() 方法类似,在队列为空时, element() 抛出一个异常,而 peek() 返回 null。
    // 获取队头元素
    E element();
    // 获取队头元素
    E peek();
    
    // put 添加一个元素 如果队列满,则阻塞
	// take 移除并返回队列头部的元素
}

package java.util;
public interface Deque<E> extends Queue<E> {}
// @since   1.6
public class ArrayDeque<E> extends AbstractCollection<E>
                           implements Deque<E>, Cloneable, Serializable{}
// @since 1.2
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable{}

JDK的官方文档不建议使用Stack实现栈的功能,转而使用Deque接口的ArrayDeque实现栈的功能。

当初 JDK1.0 在开发时,可能为了快速的推出一些基本的数据结构操作,所以推出了一些比较粗糙的类。比如,Vector、Stack、Hashtable等。这些类中的一些方法加上了 synchronized 关键字,容易给一些初级程序员在使用上造成一些误解!而且在之前的几个版本中,性能还不怎么好。

基于 Vector 实现的栈 Stack。底层实际上还是数组,所以还是存在需要扩容。Vector 是由数组实现的集合类,它包含了大量集合处理的方法。而 Stack 之所以继承 Vector,是为了复用 Vector 中的方法,来实现进栈(push)、出栈(pop)等操作。这里就是 Stack 设计不好的地方,既然只是为了实现栈,不用链表来单独实现,而是为了复用简单的方法而迫使它继承 Vector,Stack 和 Vector 本来是毫无关系的。这使得 Stack 在基于数组实现上效率受影响,另外因为继承 Vector 类,Stack 可以复用 Vector 大量方法,这使得 Stack 在设计上不严谨。

Java 提供了 Deuqe。Deque 是继承自 Queue,而 Stack 是继承自 Vector。Java 中的 Deuqe,即“double ended queue”的缩写,是 Java 中的双端队列集合类型。Deque 具备普通队列 FIFO 的功能,同时它也具备了 Stack 的 LIFO 功能,并且保留了 push 和 pop 函数,所以使用起来应该是一点障碍都没有。

ArrayDeque 是 Deque 接口的一种具体实现,是依赖于可变数组来实现的。ArrayDeque 没有容量限制,可根据需求自动进行扩容。ArrayDeque 可以作为栈来使用,效率要高于 Stack。ArrayDeque 也可以作为队列来使用,效率相较于基于双向链表的 LinkedList 也要更好一些。注意,ArrayDeque 不支持为 null 的元素。

接口方法对照:

Deque里也有offer(e)/poll()/peek()方法,底层还是调的offerLast(e)/pollFirst()/peekFirst()方法。

Deque里也有push()/pop()/peek()方法,底层还是调的addFirst()/removeFirst()/peekFirst()方法。

算法题中所用的单调栈、单调队列、优先级队列

单调栈:

Deque<Integer> stack = new ArrayDeque<Integer>();
// 栈顶加入
stack.push(i);
// 弹出栈顶
stack.pop();
// 返回栈顶
stack.peek()

单调队列

Deque<Integer> deque = new LinkedList<>();

// 返回队尾第一个元素
deque.peekLast();
// 删除队尾第一个元素
deque.pollLast();
// 从队尾加入一个元素
deque.offerLast(i);

// 返回队头第一个元素
deque.peekFirst();
// 删除队头第一个元素
deque.pollFirst();

优先级队列

// 小顶堆(默认)
PriorityQueue queue = new PriorityQueue<Integer>(
  new Comparator<Integer>() {
	        @Override
	        public int compare(Integer o1, Integer o2) {
						return o1 - o2;
	        }
	    }                                                
);

// 大顶堆
PriorityQueue queue = new PriorityQueue<Integer>(
  new Comparator<Integer>() {
	        @Override
	        public int compare(Integer o1, Integer o2) {
						return o2 - o1;
	        }
	    }                                                
);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悬浮海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值