常见面试题之栈和队列

85 阅读1分钟

1.双端链表实现栈和队列

public static class Node<T> {
        public T value;
        public Node<T> last;
        public Node<T> next;

        public Node(T data) {
            value = data;
        }
    }
//双端链表结构
public static class DoubleEndsQueue<T> {
    public Node<T> head;
    public Node<T> tail;

    public void addFromHead(T value) {
        Node<T> cur = new Node<>(value);
        if (head == null) {
            head = cur;
            tail = cur;
        } else {
            cur.next = head;
            head.last = cur;
            head = cur;
        }
    }

    public void addFromBottom(T value) {
        Node<T> cur = new Node<>(value);
        if (head == null) {
            head = cur;
            tail = cur;
        } else {
            cur.next = tail;
            tail.last = cur;
            tail = cur;
        }
    }

    public T popFromHead() {
        if (head == null) {
            return null;
        }
        Node<T> cur = head;
        if (head == tail) {
            head = null;
            tail = null;
        } else {
            head = cur.next;
            cur.next = null;
            head.last = null;
        }
        return cur.value;
    }

    public T popFromBottom() {
        if (head == null) {
            return null;
        }
        Node<T> cur = tail;
        if (head == tail) {
            head = null;
            tail = null;
        } else {
            tail = cur.last;
            cur.last = null;
            tail.next = null;
        }
        return cur.value;
    }
}
//栈的实现
public static class MyStack<T> {
    private DoubleEndsQueue<T> queue;

    public MyStack() {
        queue = new DoubleEndsQueue<>();
    }
    //从头部进
    public void push(T value) {
        queue.addFromHead(value);
    }
    //从头部出
    public T pop() {
        return queue.popFromHead();
    }
}
//队列的实现
public static class MyQueue<T> {
    private DoubleEndsQueue<T> queue;

    public MyQueue() {
        queue = new DoubleEndsQueue<>();
    }
    //从头部进
    public void push(T value) {
        queue.addFromHead(value);
    }
    //从尾部出
    public T pop() {
        return queue.popFromBottom();
    }
}

2.数组实现栈

public class ArrayStack {
    //栈的最大容量限制
    private int limit;
    private int index = 0;
    private int[] arr = null;
    public ArrayStack(int limit) {
        this.limit = limit;
        arr = new int[limit];
    }

    //index:下一个要进栈的数组下标的位置
    public void push(int value) throws Exception {
        if (limit == index) {
            throw new Exception("栈已满,无法再添加新的元素");
        }
        arr[index++] = value;
    }

    public int pop() throws Exception {
        if (index == 0) {
            throw new Exception("栈已空,拿不到东西了");
        }
        return arr[--index];
    }

    public boolean isFull() {
        return index == limit;
    }

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

    public static void main(String[] args) throws Exception {
        Random random = new Random();
        ArrayStack as = new ArrayStack(7);
        while (!as.isFull()) {
            int v = random.nextInt(10);
            as.push(v);
            System.out.print(v + "\t");
        }
        System.out.println();
        while (!as.isEmpty()) {
            System.out.print(as.pop() + "\t");
        }
    }
}

3.数组实现队列

public static class MyQueue {
    private int[] arr;
    private int pushi;
    private int polli;
    //引入size 解耦pushi、polli之间的关系
    private int size;

    private int limit;

    public MyQueue(int limit) {
        arr = new int[limit];
        pushi = 0;
        polli = 0;
        size = 0;
        this.limit = limit;
    }

    public void push(int value) throws Exception {
        if (size == limit) {
            throw new Exception("队列已满,无法添加");
        }
        size++;
        arr[pushi] = value;
        pushi = nextIndex(pushi);
    }

    public int pop() throws Exception {
        if (size == 0) {
            throw new Exception("队列已空,无法获取元素");
        }
        size--;
        int ans = arr[polli];
        polli = nextIndex(polli);
        return ans;
    }
    //获取下一个要入队或出队的位置
    private int nextIndex(int index) {
        return index < limit - 1 ? index + 1 : 0;
    }

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

public static void main(String[] args) throws Exception {
    Random random = new Random();
    MyQueue as = new MyQueue(7);
    while (!as.isFull()) {
        int v = random.nextInt(10);
        as.push(v);
        System.out.print(v + "\t");
    }
    System.out.println();
    while (!as.isEmpty()) {
        System.out.print(as.pop() + "\t");
    }
}

4.实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能
1)pop、push、getMin操作的时间复杂度都是O(1)
2) 设计的栈类型可以使用现成的栈结构

public class MyStack2 {
private Stack<Integer> stackData;
private Stack<Integer> stackMin;

public MyStack2() {
    this.stackData = new Stack<>();
    this.stackMin = new Stack<>();
}

public void push(int newNum) throws Exception {
    if (stackMin.isEmpty()) {
        stackMin.push(newNum);
    } else if (newNum < getMin()) {
        stackMin.push(newNum);
    } else {
        Integer newMin = stackMin.peek();
        stackMin.push(newMin);
    }
    stackData.push(newNum);
}

public int pop() throws Exception {
    if (stackData.isEmpty()) {
        throw new Exception("stack is empty!");
    }
    stackMin.pop();
    return stackData.pop();
}

private int getMin() throws Exception {
    if (stackMin.isEmpty()) {
        throw new Exception("stack is empty!");
    }
    return stackMin.peek();
}

}