普林斯顿公开课 算法2-8:调整数组大小

自动调整容量的数组栈
本文介绍了三种实现数组栈自动调整容量的方法,并分析了各自的性能和内存占用情况。通过对比链表栈,突出了数组栈的优势。

问题


如何实现数组栈能够自动调整容量,从而不会溢出呢?


第一种方法


每次push或pop的时候都对数组的大小进行调整。这种方法开销太大,复杂度是N^2。


所以这种方法不太合适,我们需要一种能够调整数组大小的方法,但是调整频率不太频繁。


第二种方法


push的时候,如果数组满了,就将数组的大小提高一倍

pop的时候,如果数组不到一半满,就将数组的大小减少一倍


但是这种情况下,如果刚好在边界点不断的push-pop-push-pop,那么数组就会一直调整大小,这样的开销很大。


第三种方法


因此改进方法是pop的时候,如果数组不到1/4满时,才调整数组的大小


这样,数组的使用率就在25%到100%之间。


性能分析


平均情况下的复杂度是1,最坏情况下的push和pop操作的复杂度是N。


内存分析


平均每个元素占用的空间在8到32个字节之间。


数组栈和链表栈的比较


数组栈

链表栈中所有的操作的复杂度都是1

链表栈在处理链表的时候占用了额外的内存和开销


链表栈

数组栈中平均复杂度是1

内存占用更少


代码

public class ResizeArrayStack<T> {
    private Object[] array;
    private int size;
 
    public ResizeArrayStack(){
        array = new Object[2];
    }
 
    public void push(T x) {
        if(array.length == size) resize(array.length*2);
        array[size] = x;
    }
 
    public T pop() {
        size--;
        T result = (T)array[size];
        array[size] = null;
        if(size>0 && size <= array.length/4) resize(array.length/2); // size>0不可缺少
        return result;
    }
 
    public boolean isEmpty() {
        return size==0;
    }
 
    private void resize(int n){
        Object[] a = new Object[n];
        for(int i=0;i<size;i++){
            a[i] = array[i];
        }
        array = a;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值