栈
public interface Stack<Item> extends Iterable<Item> {
boolean isEmpty();
int size();
Stack<Item> push(Item item);
Item pop() throws Exception;
}
1.数组实现
public class ResizingArrayStack<Item> implements Stack<Item> {
private Item[] a = (Item[]) new Object[1];
private int N = 0;
@Override //判断是否为空
public boolean isEmpty() {
return N == 0;
}
@Override
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;
}
@Override
public Stack<Item> push(Item item) { //入栈操作
if (N == a.length) resize(2*N);
a[N++] = item;
return this;
}
@Override
public Item pop() throws Exception {//出栈操作
if (isEmpty())
throw new Exception("Stack is empty!");
Item item = a[--N];
a[N] = null; // 避免对象游离
return item;
}
private void check(){
if (N > 0 && N == a.length/4){
resize(a.length/2);
}else if (N>a.lenth){
resize(a.length*2)
}
}
@Override
public Iterator<Item> iterator(){// 返回逆序遍历的迭代器
return new Iterator<Item>() {
private int i = N;
public boolean hasNext() {
return i > 0;
}
public Item next() {
return a[--i];
}
public void remove() {}
};
}
}
2.链表实现
需要使用链表的头插法来实现,因为头插法中最后压入栈的元素在链表的开头,它的 next 指针指向前一个压入栈的元素,在弹出元素时就可以通过 next 指针遍历到前一个压入栈的元素从而让这个元素成为新的栈顶元素.
public class ListStack<Item> implements Stack<Item> {
private Node top = null;
private int N = 0;
private class Node{
Item item;
Node next;
}
@Override
public boolean isEmpty() {
return top == null;
}
@Override
public int size() {
return N;
}
@Override
public Stack<Item> push(Item item) {
Node newTop = new Node();
newTop.item = item;
newTop.next = top;
top = newTop;
N++;
return this;
}
@Override
public Item pop() throws Exception {
if (isEmpty()){
throw new Exception("Stack is empty!");
}
Item item = top.item;
top = top.next;
N--;
return item;
}
@Override
public Iterator<Item> iterator() {
return new Iterator<Item>() {// 返回链表遍历的迭代器
private Node current = top;
public boolean hasNext() {
return current != null; // current.next != null; 错误
}
public Item next() {
Item item = current.item;
current = current.next;
return item;
}
public void remove() {}
};
}
}
队列
下面是队列的链表实现,需要维护 first 和 last 节点指针,分别指向队首和队尾。
这里需要考虑 first 和 last 指针哪个作为链表的开头。因为出队列操作需要让队首元素的下一个元素成为队首,所以需要容易获取下一个元素,而链表的头部节点的 next 指针指向下一个元素,因此可以让 first 指针链表的开头。
public interface Queue<Item> extends Iterable<Item> {
boolean isEmpty();
int size();
Queue<Item> add (Item item);
Item remove() throws Exception;
}
```
```
public class ListQueue<Item> implements Queue<Item> {
private Node first;
private Node last;
private int N = 0;
private class Node {
Item item;
Node next;
}
@Override
public boolean isEmpty() {
return first == null;
}
@Override
public int size() {
return N;
}
@Override
public Queue<Item> add (Item item){
Node newNode = new Node();
newNode.item = item;
newNode.next = null;
if (isEmpty()){
first = newNode;
} else{
last.next = newNode;
last = newNode;\
}
N++;
return this;
}
@Override
public Item remove () throws Exception {
if (isEmpty())
throw new Exception("Queue is empty!");
NODE node = first.item;
first = first.next;
N--;
if (isEmpty()){
last = null;
}
return node.item;
}
@Override
public Iterator<Item> iterator(){
return new Iterator<Item>() {
Node current = first;
public boolean hasNext() {
return current != null;
}
public Item next() {
Item item = current.item;
current = current.next;
return item;
}
public void remove() {}
};
}
}