如何自定义实现堆栈?

来源:互联网 发布:淘宝商品描述怎么写 编辑:程序博客网 时间:2024/06/02 17:08


(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/70860378冷血之心的博客)


      堆栈(Stack)是一种常见的数据结构,符合后进先出(First In Last Out)原则,通常用于实现对象存放顺序的逆序。栈的基本操作有push(添加到堆栈),pop(从堆栈删除),peek(检测栈顶元素且不删除)。


实现方式1:

使用一个队列实现,可以使用LinkedList或者ArrayDeque实现,主要是实现其常用的push、pop以及peek方法。

import java.util.ArrayDeque;import java.util.Deque;import java.util.LinkedList;public class MyStackTest{public static void main(String[] args) {MyStack<Integer> stack = new MyStack<Integer>();// 将0、1、2、3、4存入堆栈stackfor (int i = 0; i < 5; i++) {stack.push(i);}System.out.println("After pushing 5 elements: " + stack);int m = stack.pop();System.out.println("Popped element = " + m);System.out.println("After popping 1 element : " + stack);int n = stack.peek();System.out.println("Peeked element = " + n);System.out.println("After peeking 1 element : " + stack);}}class MyStack<T> {//private Deque<Integer> queue = new ArrayDeque<Integer>();private Deque<Integer> queue = new LinkedList<Integer>();    // push存入元素public void push(Integer element) {queue.addFirst(element);}// pop取出元素public Integer pop() {return queue.removeFirst();}    // peek获取元素,但是并不取出元素public Integer peek() {return queue.getFirst();}public String toString() {return queue.toString();}}
LinkedList:特有方法:
addFirst();
addLast();


getFirst();
getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException

removeFirst();
removeLast();
获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException


在JDK1.6出现了替代方法。

offerFirst();
offerLast();

peekFirst();
peekLast();
获取元素,但不删除元素。如果集合中没有元素,会返回null。



pollFirst();
pollLast();
获取元素,但是元素被删除。如果集合中没有元素,会返回null。




实现方式2:

使用int数组来实现

public class StackTest{public static void main(String[] args) {Stack2 stack = new Stack2();// 将0、1、2、3、4存入堆栈stackfor (int i = 0; i < 5; i++) {stack.push(i);}System.out.println("After pushing 5 elements: " + stack);int m = stack.pop();int m1 = stack.pop();int m2 = stack.pop();int m3 = stack.pop();System.out.println("Popped element = " + m3);System.out.println("After popping 1 element : " + stack);int n = stack.peek();System.out.println("Peeked element = " + n);System.out.println("After peeking 1 element : " + stack);}}class Stack2 {    /**     * 栈的最大深度     **/    protected int MAX_DEPTH = 10;    /**     * 栈的当前深度     */    protected int depth = 0;    /**     * 实际的栈     */    protected int[] stack = new int[MAX_DEPTH];    /**     * push,向栈中添加一个元素     *     * @param n 待添加的整数     */    protected void push(int n) {        if (depth == MAX_DEPTH - 1) {            throw new RuntimeException("栈已满,无法再添加元素。");        }        stack[depth++] = n;    }    /**     * pop,返回栈顶元素并从栈中删除     *     * @return 栈顶元素     */    protected int pop() {        if (depth == 0) {            throw new RuntimeException("栈中元素已经被取完,无法再取。");        }        // --depth,dept先减去1再赋值给变量dept,这样整个栈的深度就减1了(相当于从栈中删除)。        return stack[--depth];    }    /**     * peek,返回栈顶元素但不从栈中删除     *     * @return     */    protected int peek() {        if (depth == 0) {            throw new RuntimeException("栈中元素已经被取完,无法再取。");        }        return stack[depth - 1];    }        @Override    public String toString() {    // TODO Auto-generated method stub    return stack.toString();    }}
这种实现方式有个问题,在pop方法中,只是单纯的移动了指针,相当于从堆栈中删除了该元素,其实并没有做到真正删除。虽然也可以实现简单的堆栈功能,但会产生如图所示的现象:



其实数组中在pop一次之后,仍然存着5个元素,并没有减少,这样会导致内存泄漏的问题发生。解决办法如下:

 protected int pop() {        if (depth == 0) {            throw new RuntimeException("栈中元素已经被取完,无法再取。");        }        int result = stack[--depth];        stack[depth] = 0;        return result;    }

So,在面试的时候,建议使用队列来实现简单的堆栈哦~




如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,可以进群366533258一起交流学习哦~













1 1
原创粉丝点击