如何理解SplStack中push与add方法结合使用后的栈结构
搞懂SplStack第二次打印的结构问题
嘿,我来帮你理清楚这个SplStack的疑惑~ 先把你的代码贴出来方便对照:
$stack = new SplStack(); $stack[] = 'one2'; $stack[] = 20152; $stack[] = 'two2'; echo "<pre>"; print_r($stack); $stack->add(0, 'one'); $stack->add(1, 'two'); $stack->add(2, '2015'); echo "<pre>"; print_r($stack);
先搞明白SplStack的本质
SplStack其实是SplDoublyLinkedList(双向链表)的子类,它默认是LIFO(后进先出)的栈模式——正常情况下,你用$stack[] = ...或者push()都是往栈顶加元素,pop()是从栈顶取元素。
但关键来了:add()方法是直接继承自父类SplDoublyLinkedList的,它根本不遵守栈的LIFO规则,而是直接操作双向链表的底层索引位置!
拆解两次打印的逻辑
第一次print_r的结构
你用$stack[]添加元素,相当于调用push(),元素会被放到栈顶(也就是双向链表的尾部)。此时双向链表的底层顺序(从链表头部到尾部)是:one2 → 20152 → two2
而SplStack的print_r输出是从栈顶到栈底的顺序,所以第一次打印的元素顺序是:two2、20152、one2(和你看到的结果一致)。
第二次print_r的结构
你调用的add($index, $value)是直接在双向链表的指定索引位置插入元素,这里的索引是双向链表的底层索引:
- 双向链表的索引
0对应的是链表头部(也就是SplStack的栈底),不是栈顶! - 每一次
add都会把元素插入到指定索引的位置,后面的元素自动后移。
我们一步步看:
$stack->add(0, 'one'):在链表头部(栈底)插入one,此时链表顺序变成:one→one2→20152→two2$stack->add(1, 'two'):在链表索引1的位置(one和one2之间)插入two,链表顺序:one→two→one2→20152→two2$stack->add(2, '2015'):在链表索引2的位置(two和one2之间)插入2015,链表顺序:one→two→2015→one2→20152→two2
而SplStack的print_r依然是从栈顶到栈底输出,栈顶是链表的尾部two2,所以第二次打印的元素顺序会是:two2、20152、one2、2015、two、one
总结一下
如果想严格按照栈的规则操作SplStack,别用add()方法,应该用push()(加栈顶)和pop()(取栈顶)。add()是绕开栈的规则直接操作底层双向链表的,所以才会出现你看不懂的结构~
内容的提问来源于stack exchange,提问作者user9718914
相关产品推荐
相关产品推荐

