栈的使用和模拟

来源:互联网 发布:淘宝还可以买梦幻币吗 编辑:程序博客网 时间:2024/06/05 18:55

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">目录:</span>

1.JDK中的栈

2.顺序栈的原理

3.顺序栈的实现

4.功能对比

5.性能测试

首先来看一下JDK中为我们提供的栈,分别有:

1.顺序栈 java.util.stack

2.链式栈java.util.LinkedList



栈中的方法void push(E e)将元素压入栈中E peek()查看栈顶元素,不弹出E Pop()弹出栈顶元素,并返回boolean isEmpty()判断栈是否为空int size()取得栈中的元素个数顺序栈,继承Vector,Vector和arrayList很相似,都是动态的顺序表。

Vector是线程安全的,ArrayList是异步的。在Vector的底层实现中,包含很多Synchrionized这个关键字。

理解stack原理的关键:

1.内部数组及其容量。

2.栈顶指针top

3.动态扩容



下面是一个微型栈的实现代码

public class CustomStack<T> {    private int size;    private Object[] array=new Object[4];    public boolean isEmpty(){        if (size==0){            return true;        }else{            return false;        }    }    public int size(){        return size;    }    public void expandCapacity(){        Object[] newArray=new Object[size*2];        System.arraycopy(array,0,newArray,0,size);        array=newArray;    }    public void push(T t){        array[size]=t;        size++;        if (size==array.length){            expandCapacity();        }    }    public T peek(){        if (isEmpty()){            return null;        }else{            return (T) array[size-1];        }    }    public T pop(){        if (isEmpty()){            return null;        }else{            T t=peek();            array[size-1]=null;            size--;//把栈顶指针向下移动一位            return t;        }    }}


然后对自己实现的栈进行测试:

新建自己的栈和JDK的栈

进行100万次以上的push()、peek()、以及pop()

断言两个栈的元素个数、栈顶元素完全相同


测试的代码如下:

  final int Max=1<<20;    @Test    public void testFunction(){        Stack<Integer> stack1=new Stack<>();        CustomStack<Integer> stack2= new CustomStack<>();        Random ra=new Random();        System.out.println(Max+"");        int value=0;        for (int i=0;i<=Max;i++){            value=ra.nextInt();            if (value%4!=0){                stack1.push(value);                stack2.push(value);            }else if(!stack1.isEmpty()&&!stack2.isEmpty()){                Assert.assertTrue(stack1.size()==stack2.size());                Assert.assertTrue(stack1.peek().equals(stack2.peek()));            }        }        while(!stack1.isEmpty()){            Assert.assertTrue(stack1.pop().equals(stack2.pop()));        }    }


测试结果表明,自定义的栈是没有问题的。

然后对栈的性能进行比较:

1.让JDK的顺序栈进行一千万次左右的push()、peek()、pop();

2.让JDK的链式栈进行一千万次左右的push()、peek()、pop();

3.让自定义的栈进行一千万次左右的push()、peek()、pop();

测试代码:

public class TestSpeed {    final int Max=1<<23;    @Test    public void testStackSpeed(){        Stack<Integer> stack1=new Stack<>();        Random ra=new Random();        int value=0;        for (int i=0;i<=Max;i++){            value=ra.nextInt();            if (value%4!=0){                stack1.push(value);            }else if(!stack1.isEmpty()){                stack1.peek();            }        }        while(!stack1.isEmpty()){            stack1.pop();        }    }    @Test    public void testLinkedSpeed(){        LinkedList<Integer> stack1=new LinkedList<>();        Random ra=new Random();        int value=0;        for (int i=0;i<=Max;i++){            value=ra.nextInt();            if (value%4!=0){                stack1.push(value);            }else if(!stack1.isEmpty()){                stack1.peek();            }        }        while(!stack1.isEmpty()){            stack1.pop();        }    }    @Test    public void testCustomSpeed(){        CustomStack<Integer> stack1=new CustomStack<>();        Random ra=new Random();        int value=0;        for (int i=0;i<=Max;i++){            value=ra.nextInt();            if (value%4!=0){                stack1.push(value);            }else if(!stack1.isEmpty()){                stack1.peek();            }        }        while(!stack1.isEmpty()){            stack1.pop();        }    }}
测试结果:


结果表明,链式的栈运行速度是最慢的。

0 0