1、栈
Stack是一个类,继承Vector类,无参构造。
public
class Stack<E> extends Vector<E> {
/**
* Creates an empty Stack.
*/
public Stack() {
}
}
栈数据结构一般用于树的先序、中序、后序遍历,虽然后序没有写过迭代版,但是中序和先序的遍历都是用栈这种数据结构实现的。
由于Stack类继承自Vector类,所以Stack的方法基本都是直接调用Vector类的方法。
集合类存储的都是引用类型的元素,比如TreeNode、Integer等。所以统一表现在泛型。
常用方法:
0、创建
//栈
Stack<Integer> stack = new Stack<>();
1、添加 push
栈顶添加
public E push(E item) {
addElement(item);
return item;
}
返回值不重要。
2、删除 pop
栈顶删除
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
删除栈顶元素,返回值重要,存在返回值,就是栈顶元素。
3、查看栈顶元素
仅仅是查看,不会删除
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
返回值重要,返回栈顶元素。
4、判断栈是否为空
public boolean empty() {
return size() == 0;
}
当然,由于Vector类同样会实现Collection接口的isEmpty()
方法,所以,在Stack中,同样可以使用isEmpty()
来判断栈是否为空。
总结:一个空参构造、一个push、一个pop、一个peek、一个empty。
2、队列
队列的数据结构,和栈有所差异,队列是先进先出,即在尾部添加,头部删除。
在Java中,队列Queue是一个接口,并不是一个类,在这点上与Stack有所不同。
public interface Queue<E> extends Collection<E> {}
所以我们创建对象的语法为:
//Queue
Queue<Integer> queue = new LinkedList<>();
Queue<Integer> queue1 = new PriorityQueue<>();
因为LinkedList和PriorityQueue都实现了Queue接口中定义的方法,那么我们在使用时,只需要调用接口中的方法即可,在运行时,自动执行子类中的方法。
1、添加
boolean add(E e);
boolean offer(E e); //推荐,以便区分List接口
2、删除
E remove();
E poll(); //推荐,以便区分List接口
3、查看队列头
E element(); //推荐,以便和Stack区分
E peek();
4、判断队列是否为空
如果是判断队列是否为空,则使用Queue继承Collection接口的isEmpty()
方法。
3、双端队列
双端队列,顾名思义,队列头部和尾部都可以进行添加、删除、查看。
和队列一致,双端队列在Java中同样是一个接口,并且是Queue的子接口。
public interface Deque<E> extends Queue<E> {}
所以创建对象的语法:
//Deque
Deque<Integer> deque = new LinkedList<>();
1、添加(头部添加、尾部添加)
void addFirst(E e);
void addLast(E e);
boolean offerFirst(E e); //推荐,offer更像是Queue的操作,区分List
boolean offerLast(E e); //推荐
2、删除(头部删除、尾部删除)
E removeFirst();
E removeLast();
E pollFirst(); //推荐
E pollLast(); //推荐
3、查看(查看头节点、查看尾结点)
E getFirst();
E getLast();
E peekFirst(); //推荐
E peekLast(); //推荐
4、判断双端队列是否为空
同样的,使用Deque继承Queue继承Collection接口的isEmpty()
方法。
4、哈希表
在LeetCode中常常会用到哈希表,那么在用到时,基本都是使用Java中的HashMap类。
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {}
常用的是HashMap,但是偶尔可能会用LinkedHashMap。
创建对象的语法:
//哈希
HashMap<Integer,Integer> hashMap = new HashMap<>();
1、添加
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
2、获取
根据键获取值
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
3、判断是否包含某个键
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
4、判断哈希表是否为空
public boolean isEmpty() {
return size == 0;
}
5、删除
根据键删除某个键值对
public V remove(Object key) {
Node<K,V> e;
return (e = removeNode(hash(key), key, null, false, true)) == null ?
null : e.value;
}
6、判断是否包含值
(不常用)
public boolean containsValue(Object value) {}
7、获取所有键的集合
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
8、获取所有值
public Collection<V> values() {}
9、获取所有键值对
public Set<Map.Entry<K,V>> entrySet() {
Set<Map.Entry<K,V>> es;
return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
}
获取到键值对的Set集合后,遍历,getKey()
、getValue()
即可。