算法(二)栈和队列

> First-In-Last-Out

1. 数组实现

public class ResizeArrayStack implements Iterable {
    private Item[] a = (Item[]) new Object[1];
    private int N = 0;

    public void push(Item item) {
        if (N >= a.length) {
            resize(2 * a.length);
        }
        a[N++] = item;
    }

    public Item pop() {
        Item item = a[--N];
        if (N <= a.length / 4) {
            resize(a.length / 2);
        }
        return item;
    }

    // 调整数组大小,使得栈具有伸缩性
    private void resize(int size) {
        Item[] tmp = (Item[]) new Object[size];
        for (int i = 0; i < N; i++) {
            tmp[i] = a[i];
        }
        a = tmp;
    }

    public boolean isEmpty() {
        return N == 0;
    }

    public int size() {
        return N;
    }

    @Override
    public Iterator iterator() {
        // 需要返回逆序遍历的迭代器
        return new ReverseArrayIterator();
    }

    private class ReverseArrayIterator implements Iterator {
        private int i = N;

        @Override
        public boolean hasNext() {
            return i > 0;
        }

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

2. 链表实现

需要使用链表的头插法来实现,因为头插法中最后压入栈的元素在链表的开头,它的 next 指针指向前一个压入栈的元素,在弹出元素使就可以通过 next 指针遍历到前一个压入栈的元素从而让这个元素称为新的栈顶元素。

public class Stack {

    private Node top = null;
    private int N = 0;

    private class Node {
        Item item;
        Node next;
    }

    public boolean isEmpty() {
        return N == 0;
    }

    public int size() {
        return N;
    }

    public void push(Item item) {
        Node newTop = new Node();
        newTop.item = item;
        newTop.next = top;
        top = newTop;
        N++;
    }

    public Item pop() {
        Item item = top.item;
        top = top.next;
        N--;
        return item;
    }
}

队列

> First-In-First-Out

下面是队列的链表实现,需要维护 first 和 last 节点指针,分别指向队首和队尾。

这里需要考虑 first 和 last 指针哪个作为链表的开头。因为出队列操作需要让队首元素的下一个元素成为队首,所以需要容易获取下一个元素,而链表的头部节点的 next 指针指向下一个元素,因此可以让 first 指针链表的开头。

public class Queue {
    private Node first;
    private Node last;
    int N = 0;
    private class Node{
        Item item;
        Node next;
    }

    public boolean isEmpty(){
        return N == 0;
    }

    public int size(){
        return N;
    }

    // 入队列
    public void enqueue(Item item){
        Node newNode = new Node();
        newNode.item = item;
        newNode.next = null;
        if(isEmpty()){
            last = newNode;
            first = newNode;
        } else{
            last.next = newNode;
            last = newNode;
        }
        N++;
    }

    // 出队列
    public Item dequeue() {
        if (isEmpty()) return null;
        Node node = first;
        first = first.next;
        N--;
        if (isEmpty()) last = null;
        return node.item;
    }
}
本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
极客文库 » 算法(二)栈和队列

Leave a Reply

欢迎加入「极客文库」,成为原创作者从这里开始!

立即加入 了解更多