7.1 双单向链表
3 分钟阅读
原文链接: https://rust-unofficial.github.io/too-many-lists/infinity-double-single.html
我们在双向链表上挣扎,是因为所有权语义纠缠不清:没有哪个节点严格「拥有」另一个节点。但我们之所以挣扎,是因为带着对链表是什么的成见——默认所有链接都朝同一方向。
不如把链表劈成两半:一半向左,一半向右:
| |
| |
现在不再只是安全的栈,而是通用链表。可以从任一端 push 向左或向右增长;也可以从一端 pop、推到另一端来「走」链表。为避免多余分配,复制安全 Stack 的源码以访问其私有细节:
| |
稍微改一下 push 和 pop:
| |
现在可以写 List 了:
| |
常规操作:
| |
最有趣的是可以四处走:
| |
返回 bool 只是方便表示是否真的移动了。来测一下:
| |
| |
这是finger 数据结构的极端例子:在结构里维护某种「手指」,因此能在与手指距离成正比的时间内支持位置上的操作。
在手指附近改链表很快;要改远处就得一路走过去。可以永久移过去(把元素从一个栈挪到另一个),或临时沿链接用 &mut 走过去改。但 &mut 不能沿链表往回走,而手指可以!