diff --git a/notes/算法 - 栈和队列.md b/notes/算法 - 栈和队列.md index 7784b628..bdd14643 100644 --- a/notes/算法 - 栈和队列.md +++ b/notes/算法 - 栈和队列.md @@ -27,6 +27,8 @@ public interface MyStack extends Iterable { ### 1. 数组实现 +数组满时容量翻倍,元素数量降到容量的 1/4 时容量减半。不在半满时就减半,是为了避免抖动:例如容量为 4 且已满时 push 一次,扩容到 8;如果半满就减半,接着 pop 一次,元素回到 4 个,又缩回 4。之后交替 push 和 pop,每次操作都要复制全部元素。 + ```java public class ArrayStack implements MyStack { @@ -126,7 +128,7 @@ public class ArrayStack implements MyStack { ### 2. 链表实现 -需要使用链表的头插法来实现,因为头插法中最后压入栈的元素在链表的开头,它的 next 指针指向前一个压入栈的元素,在弹出元素时就可以通过 next 指针遍历到前一个压入栈的元素从而让这个元素成为新的栈顶元素。 +栈顶放在链表头部,使用头插法:push 时新节点的 next 指向原来的栈顶,pop 时栈顶移到 next 指向的节点,两个操作都是 O(1)。如果栈顶放在链表尾部,pop 时需要找到尾节点的前一个节点,单链表只能从头遍历。 ```java public class ListStack implements MyStack { @@ -215,7 +217,7 @@ public class ListStack implements MyStack { 下面是队列的链表实现,需要维护 first 和 last 节点指针,分别指向队首和队尾。 -这里需要考虑 first 和 last 指针哪个作为链表的开头。因为出队列操作需要让队首元素的下一个元素成为队首,所以需要容易获取下一个元素,而链表的头部节点的 next 指针指向下一个元素,因此可以让 first 指针指向链表的开头。 +队首放在链表头部,队尾放在链表尾部:入队时在 last 后面追加,出队时 first 移到 next 指向的节点,两个操作都是 O(1)。如果反过来,出队要删除尾节点,需要找到它的前一个节点,单链表只能从头遍历。 ```java public interface MyQueue extends Iterable {