栈和队列

栈:又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
这里写图片描述

栈的基本操作原则是先进后出
这里写图片描述

队列:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
这里写图片描述

栈的各种操作(Java实现)

public class ArrayStack<E> {
    private static final int INITIAL_SIZE = 6;
    private E[] elementData;
    private int top; // 指向下一个空位置

    public ArrayStack(int intialSize) {
        E[] data = (E[]) new Object[intialSize];
        elementData = data;
        top = 0;
    }

    public ArrayStack() { this(INITIAL_SIZE); }

    public E get(int i) {
        checkIndex(i);
        return elementData[i];
    }

    public E top() {
        return get(top - 1);
    }

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

    public int size() {
        return top;
    }

    public void push(E elem) {
        ensureSize(top + 1);        
        elementData[top++] = elem;
    }

    public E pop() {
        int t = top - 1;
        E v = get(t);
        elementData[t] = null; // happy GC
        top = t;
        return v;
    }

    /**
     * 弹出n个元素,返回最后被弹出的元素。
     * @param n
     * @return
     */
    public E pop(int n) {
        int t = top - n;
        E v = get(t);
        for (int i = t; i < top; i++) {
            elementData[i] = null; // happy GC
        }
        top = t;
        return v;
    }

    private void ensureSize(int size) {
        if (elementData.length < size) {
            int newLength = Math.max(elementData.length << 1, size);
            E[] newData = (E[]) new Object[newLength];
            System.arraycopy(this.elementData, 0, newData, 0, this.elementData.length);
            this.elementData = newData;
        }
    }

    private void checkIndex(int i) {
        if (i < 0 || i>= top) {
            throw new IndexOutOfBoundsException("index " + i + " not in [0, " + (top - 1) + "]");
        }
    }
}

队列的各种操作(Java实现)

public class IntArrayQueue {
    private static final int INITIAL_SIZE = 8;

    private static final boolean CHECK_INVARIANT = true;

    private int[] elementData;
    private int head; // 队列头
    private int tail; // 队列尾,指向下一个空位置
    private int size;

    public IntArrayQueue(int initialSize) {
        elementData = new int[initialSize];
    }

    public IntArrayQueue() {
        this(INITIAL_SIZE);
    }

    public int size() {
        return size;
    }

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

    public void enqueue(int i) {
        ensureSize(size + 1);
        elementData[tail] = i;
        tail = incAndRound(tail);
        size++;

        if (CHECK_INVARIANT) {
            checkInvariant();
        }
    }

    private int incAndRound(int i) {
        ++i;
        if (i == elementData.length) {
            i = 0;
        }
        return i;
    }

    private void ensureSize(int newSize) {
        if (elementData.length < newSize) {
            int[] oldData = this.elementData;
            int[] newData = new int[Math.max(elementData.length << 1, newSize)];
            if (size == 0) {
                // do nothing
            } else if (tail > head) {
                System.arraycopy(oldData, head, newData, 0, size);
            } else {
                System.arraycopy(oldData, head, newData, 0, oldData.length - head);
                System.arraycopy(oldData, 0, newData, oldData.length - head, tail);
            }
            this.elementData = newData;
            head = 0;
            tail = size;
        }
    }

    public int dequeue() {
        if (size == 0) {
            throw new IndexOutOfBoundsException("Cannot dequeue empty queue");
        }
        int result = elementData[head];
        head = incAndRound(head);
        size--;

        if (CHECK_INVARIANT) {
            checkInvariant();
        }
        return result;
    }

    public int peek() {
        if (size == 0) {
            throw new IndexOutOfBoundsException("queue is empty");
        }
        return elementData[head];
    }

    private void checkInvariant() {
        if (size == 0) {
            if (head != tail) {
                throw new RuntimeException("when size = 0, head(" + head + ") != tail(" + tail + ")");
            }
        } else {
            if (tail > head) {
                if (size != (tail - head)) {
                    throw new RuntimeException("when tail > head, size(" + size + ") != tail(" + tail+") - head(" + head + ")");
                }
            } else {
                if (size != (tail - head + elementData.length)) {
                    throw new RuntimeException("when tail <= head, size != tail(" + tail + ") - head(" + head + ") + elementData.length(" + elementData.length + ")");
                }
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值