栈和队列实现+面试题

数组实现栈

package com.lzf2.class02;

import java.util.Stack;

/**
 * 数组实现栈
 */
public class ArrayImplStack {
    private int[] element;
    private int size;

    public ArrayImplStack(int capacity) {
        element = new int[capacity];
        size = 0;
    }
    public void push(int item){
        if(size <=element.length){
            throw new RuntimeException("栈满了,不要在加了");
        }
        //加入元素
        this.element[size++] = item;
    }
    public int pop(){
        if(size == 0){
            throw new RuntimeException("栈空了,不要在拿了");
        }
        //弹出元素
        return element[--size];
    }
    public int peek(){
        if(size == 0){
            throw new RuntimeException("栈空了,不要在看了");
        }
        int peekIndex = size - 1;
        return element[peekIndex];
    }
    public boolean empty(){
        return size == 0;
    }

}

链表实现栈

package com.lzf2.class02;

/**
 * 链表实现栈
 */
public class LinkedImplStack {
    //单链表节点
    private class Node{
        int value;
        Node Next;

        public Node(int value) {
            this.value = value;
        }
    }

    private Node head;
    private int size;

    public LinkedImplStack() {
        this.head = null;
        size = 0;
    }
    public void push(int item){
        Node newNode = new Node(item);
        newNode.Next = head;
        head = newNode;
        size++;
    }
    public int pop(){
        if(size == 0){
            throw new RuntimeException("栈空了,不要在拿了");
        }
        int result = head.value;
        head = head.Next;
        size--;
        return result;
    }
    public int peek(){
        if(size == 0){
            throw new RuntimeException("栈为空");
        }
        return head.value;
    }
    public boolean empty(){
        return size == 0;
    }
}

数组实现队列

package com.lzf2.class02;

/**
 * 数组实现队列
 */
public class ArrayImplQueue {
    private int[] element;
    private int pushIndex;
    private int popIndex;
    private int size;

    public ArrayImplQueue(int capacity) {
        element = new int[capacity];
        pushIndex = 0;
        popIndex = 0;
        size = 0;
    }

    public void push(int item) {
        if (size == element.length) {
            throw new RuntimeException("队列满了");
        }
        element[pushIndex] = item;
        pushIndex = indexNext(pushIndex);
        size++;
    }

    public int pop() {
        if (size == 0) {
            throw new RuntimeException("队列空");
        }
        int result = element[popIndex];
        popIndex = indexNext(popIndex);
        size--;
        return result;
    }

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

    private int indexNext(int index) {
        return index == element.length - 1 ? 0 : index + 1;
    }
}

链表实现队列

package com.lzf2.class02;

import java.util.LinkedList;
import java.util.PriorityQueue;
/**
 * 链表实现队列 
 */
public class LinkedImplQueue {
    //单链表节点
    private class Node {
        int value;
        Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    private Node head;
    private int size;
    private Node last;

    public LinkedImplQueue() {
        this.head = null;
        size = 0;
    }

    public void push(int item){
        Node newNode = new Node(item);
        if(head == null){//没有元素的时候
            head = newNode;
            last = newNode;
            size++;
            return;
        }
        last.next = newNode;
        size++;
    }
    public int pop(){
        if(size == 0){
            throw new RuntimeException("队列空");
        }
        int result = head.value;
        head = head.next;
        size--;
        return result;
    }

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

}

第一题

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

提示:两个栈实现,一个数据栈,一个最小值栈

package com.lzf.class02;

import java.util.Stack;

/**
 * 实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能
 * 	pop、push、getMin操作的时间复杂度都是 O(1)。
 * 	设计的栈类型可以使用现成的栈结构。
 *
 *  用两个栈实现,一个数据栈,一个最小值栈
 *      1)每次放入数据栈的数据newData,都去和最小值栈的栈顶数比较
 *          newData更小或等于时,就放入最小值栈。反之就不放
 *      2)每次拿出数据栈的数据时,都去和最小值的栈顶比较
 *          如果相等,就弹出最小值栈的栈顶元素
 *      3)getMin则只需要去最小值栈peek就可以
 */
public class GetMinStack {
    private Stack<Integer> stackData;//数据栈
    private Stack<Integer> stackMin;//最小值栈

    public GetMinStack() {
        stackData = new Stack<>();
        stackMin = new Stack<>();
    }
    public void push(int newNum) {
        if(stackMin.isEmpty()){
            //最小值栈为空,直接放进去
            stackMin.push(newNum);
        }else if(newNum<=this.getMin()){
            //newNum比数据栈的栈顶元素小,放入最小值栈
            stackMin.push(newNum);
        }
        this.stackData.push(newNum);
    }

    public int pop() {
        if (this.stackData.isEmpty()) {
            throw new RuntimeException("Your stack is empty.");
        }
        Integer value = stackData.pop();
        if(value==getMin()){
            stackMin.pop();
        }
        return value;
    }

    public int getMin(){
        if(this.stackMin.isEmpty()){
            throw new RuntimeException("Your stack is empty.");
        }
        return this.stackMin.peek();
    }
}

第二题

问题描述:如何用栈结构实现队列结构

提示:两个栈

package com.lzf.class02;

import java.util.Stack;

/**
 * 两个栈实现队列
 * 两个原则
 *  1.倒数据要倒干净
 *  2.数据未拿完,不能倒数据
 */
public class TwoStacksImplementQueue {
    public static class TwoStacksQueue {
        private Stack<Integer> stackPush;
        private Stack<Integer> stackPop;
        public TwoStacksQueue() {
            stackPush = new Stack();
            stackPop = new Stack();
        }
        // push栈向pop栈倒入数据
        private void pushToPop() {
            //pop为空才能倒
            if(stackPop.isEmpty()){
                //倒要倒干净
                while (!stackPush.isEmpty()){
                    stackPop.push(stackPush.pop());
                }
            }
        }
        //入队
        public void add(int value){
            stackPush.push(value);
            pushToPop();
        }
        //出队
        public int poll() {
            if (stackPop.empty() && stackPush.empty()) {
                throw new RuntimeException("Queue is empty!");
            }
            pushToPop();
            return stackPop.pop();
        }
        public int peek(){
            if (stackPop.empty() && stackPush.empty()) {
                throw new RuntimeException("Queue is empty!");
            }
            pushToPop();
            return stackPop.peek();
        }
    }
    public static void main(String[] args) {
        TwoStacksQueue test = new TwoStacksQueue();
        test.add(1);
        test.add(2);
        test.add(3);
        System.out.println(test.peek());
        System.out.println(test.poll());
        System.out.println(test.peek());
        System.out.println(test.poll());
        System.out.println(test.peek());
        System.out.println(test.poll());
    }
}

第三题

问题描述:如何用队列结构实现栈结构

提示:两个队列

package com.lzf.class02;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * 两个队列实现栈
 *
 */
public class TwoQueueImplementStack {
    public static class TwoQueueStack<T>{
        private Queue<T> queue;
        private Queue<T> help;

        public TwoQueueStack() {
            queue = new LinkedList<>();
            help = new LinkedList<>();
        }

        public void push(T value) {
            //offer和add
            //向满队列添加数据时,add为抛出异常,offer则会返回false
            queue.offer(value);
        }
        public T poll() {
            //留一个数,其余数放到另外一个队列。返回剩下的那个数
            while (queue.size()>1){
                help.offer(queue.poll());
            }
            T ans = queue.poll();
            Queue<T> temp = queue;
            queue = help;
            help = temp;
            return ans;
        }
        public T peek() {
            while (queue.size()>1){
                help.offer(queue.poll());
            }
            T ans = queue.poll();
            help.offer(ans);
            Queue<T> tmp = queue;
            queue = help;
            help = tmp;
            return ans;
        }
        public boolean isEmpty() {
            return queue.isEmpty();
        }
    }
    public static void main(String[] args) {
        System.out.println("test begin");
        TwoQueueStack<Integer> myStack = new TwoQueueStack<>();
        Stack<Integer> test = new Stack<>();
        int testTime = 1000000;
        int max = 1000000;
        for (int i = 0; i < testTime; i++) {
            if (myStack.isEmpty()) {
                if (!test.isEmpty()) {
                    System.out.println("Oops");
                }
                int num = (int) (Math.random() * max);
                myStack.push(num);
                test.push(num);
            } else {
                if (Math.random() < 0.25) {
                    int num = (int) (Math.random() * max);
                    myStack.push(num);
                    test.push(num);
                } else if (Math.random() < 0.5) {
                    if (!myStack.peek().equals(test.peek())) {
                        System.out.println("Oops");
                    }
                } else if (Math.random() < 0.75) {
                    if (!myStack.poll().equals(test.pop())) {
                        System.out.println("Oops");
                    }
                } else {
                    if (myStack.isEmpty() != test.isEmpty()) {
                        System.out.println("Oops");
                    }
                }
            }
        }

        System.out.println("test finish!");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值