You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何理解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都会把元素插入到指定索引的位置,后面的元素自动后移。

我们一步步看:

  1. $stack->add(0, 'one'):在链表头部(栈底)插入one,此时链表顺序变成:one → one2 → 20152 → two2
  2. $stack->add(1, 'two'):在链表索引1的位置(one和one2之间)插入two,链表顺序:one → two → one2 → 20152 → two2
  3. $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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:34:11