|
|
|
@ -236,7 +236,9 @@ comments: true
|
|
|
|
|
|
|
|
|
|
### 基于链表的实现
|
|
|
|
|
|
|
|
|
|
使用「链表」实现栈时,将链表的尾结点看作栈顶即可。
|
|
|
|
|
使用「链表」实现栈时,将链表的头结点看作栈顶,尾结点看作栈底。
|
|
|
|
|
|
|
|
|
|
对于入栈操作,将元素插入到链表头部即可,这种结点添加方式被称为“头插法”。而对于出栈操作,则将头结点从链表中删除即可。
|
|
|
|
|
|
|
|
|
|
受益于链表的离散存储方式,栈的扩容更加灵活,删除元素的内存也会被系统自动回收;缺点是无法像数组一样高效地随机访问,并且由于链表结点需存储指针,导致单个元素占用空间更大。
|
|
|
|
|
|
|
|
|
@ -592,7 +594,7 @@ comments: true
|
|
|
|
|
|
|
|
|
|
### 基于数组的实现
|
|
|
|
|
|
|
|
|
|
使用「数组」实现栈时,将数组的尾部当作栈顶。准确地说,我们需要使用「列表」,因为入栈的元素可能是源源不断的,因此使用动态数组可以方便扩容。
|
|
|
|
|
使用「数组」实现栈时,将数组的尾部当作栈顶,这样可以保证入栈与出栈操作的时间复杂度都为 $O(1)$ 。准确地说,由于入栈的元素可能是源源不断的,我们需要使用可以动态扩容的「列表」。
|
|
|
|
|
|
|
|
|
|
基于数组实现的栈,优点是支持随机访问,缺点是会造成一定的空间浪费,因为列表的容量始终 $\geq$ 元素数量。
|
|
|
|
|
|
|
|
|
|