问题
如何实现数组栈能够自动调整容量,从而不会溢出呢?
第一种方法
每次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;
}
}