stack结构 java_Java数据结构漫谈-Stack

标签:

Stack(栈)是一种比较典型的数据结构,其元素满足后进先出(LIFO)的特点。

Java中Stack的实现继承自Vector,所以其天然的具有了一些Vector的特点,所以栈也是线程安全的。

class Stack extends Vector {

事实上,除了继承自Vector的那些方法之外,Stack只提供了5个方法:

publicE push(E item) {

addElement(item);returnitem;

}public synchronizedE pop() {

E obj;int len =size();

obj=peek();

removeElementAt(len- 1);returnobj;

}public synchronizedE peek() {int len =size();if (len == 0)throw newEmptyStackException();return elementAt(len - 1);

}public booleanempty() {return size() == 0;

}public synchronized intsearch(Object o) {int i =lastIndexOf(o);if (i >= 0) {return size() -i;

}return -1;

}

push函数是用来向Stack的顶部压入一个元素,影响其性能的是 addElement的性能:

public synchronized voidaddElement(E obj) {

modCount++;

ensureCapacityHelper(elementCount+ 1);

elementData[elementCount++] =obj;

}

可以看出,其方法是在Vector的最后加入一个元素,其时间复杂度是o(1)。

peek函数是从查看栈顶元素,但是不删除。其性能主要是由Vector的elementAt函数决定的:

public synchronized E elementAt(intindex) {if (index >=elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " +elementCount);

}returnelementData(index);

}

E elementData(intindex) {return(E) elementData[index];

}

由于Vector的底层是数组实现的,通过下标可以直接进行定位,所以peek的时间复杂度也是o(1)。

pop函数是移除并获取到栈顶元素,在源码中可以看到,这里调用peek获取了栈顶元素,使用removeElementAt来删除栈顶元素,这个函数也正是决定pop性能的关键:

public synchronized void removeElementAt(intindex) {

modCount++;if (index >=elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " +elementCount);

}else if (index < 0) {throw newArrayIndexOutOfBoundsException(index);

}int j = elementCount - index - 1;if (j > 0) {

System.arraycopy(elementData, index+ 1, elementData, index, j);

}

elementCount--;

elementData[elementCount]= null; /*to let gc do its work*/}

咋一看来,这里删除一个元素之后,都会对数组中的元素进行复制调整,时间复杂度是o(n),但是考虑到传进来的index值的特殊性:

index = elementCount -1;

这样的话if(j>0)的条件永远都不会成立,因为j永远都是0,中间复制调整元素的操作就避免了,仅仅是在最后把Vector最后的值赋值为null,时间复杂度是o(1)。

search是查找一个元素在Stack中的index,这里起作用的是Vector的lastIndexOf函数,代码如下:

public synchronized intlastIndexOf(Object o) {return lastIndexOf(o, elementCount-1);

}public synchronized int lastIndexOf(Object o, intindex) {if (index >=elementCount)throw new IndexOutOfBoundsException(index + " >= "+elementCount);if (o == null) {for (int i = index; i >= 0; i--)if (elementData[i]==null)returni;

}else{for (int i = index; i >= 0; i--)if(o.equals(elementData[i]))returni;

}return -1;

}

可以看出,查找的过程是从后向前,挨个比较,其时间复杂度必然是o(n)。

Stack是Vector的子类,所以Vector的函数这里也适用,这里不再赘述,在Vector相关的介绍文章中会有。

Stack是线程安全的,所以其性能必然受到影响,如果需要使用一个非线程安全的Stack,可以直接使用LinkedList,LinkedList本身提供的方法就包含了Stack的操作。

标签:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值