承接兄弟遍歷,本篇實作葉子遍歷迭代器:訪問以給定節點為根的子樹中**所有葉子節點**(無孩子節點)。同樣支援正向/反向、const/非 const 四種型別。
template<bool is_const, bool is_reverse>
class leaf_iterator_impl : public iterator_base_impl<is_const> { ... };
using leaf_iterator = leaf_iterator_impl<false, false>;
using reverse_leaf_iterator = leaf_iterator_impl<false, true>;
using const_leaf_iterator = leaf_iterator_impl<true, false>;
using const_reverse_leaf_iterator = leaf_iterator_impl<true, true>;
節點欄位:first_child, last_child, next_sibling, prev_sibling, parent (偏移量)。
forward_firstoff_ = root_;
while (node->first_child_) {
off_ += node->first_child_; // 往最左孩子走
node = &(*tree_)[off_];
}
// 當前節點無 first_child → 葉子
forward_lastoff_ = root_;
while (node->last_child_) {
off_ += node->last_child_; // 往最右孩子走
node = &(*tree_)[off_];
}
forward_nextoff_ -= parent),直到找到有右兄弟或到根。end()。
3. 否則:跳至右兄弟 (off_ += next_sibling),再一直向下走最左孩子 直到葉子。
forward_prev鏡像邏輯:向上找左兄弟 → 跳至左兄弟 → 一直走最右孩子到葉子。
從基底迭代器轉換時,root_ = off_(以當前節點為子樹根)。葉子遍歷不離開此子樹範圍。
mtree<int,false>::iterator_base node = ...;
// 正向遍歷子樹所有葉子
auto it = node.leaf_begin();
auto last = --it.end();
for (it = it.begin(); it != it.end(); ++it) {
cout << *it;
if (it != last) cout << ' ';
}
// 反向遍歷
auto rit = node.reverse_leaf_begin();
auto rlast = --rit.end();
for (rit = rit.begin(); rit != rit.end(); ++rit) { ... }
| 特性 | 兄弟遍歷 | 葉子遍歷 |
|---|---|---|
| 遍歷範圍 | 同層級同胞節點 | 子樹所有葉子 (跨層級) |
| 導航核心 | 水平鏈表 (next/prev_sibling) | 深度優先回溯 + 水平跳轉 |
| root_ 語意 | 父節點 (界定同胞範圍) | 子樹根節點 (界定遞歸範圍) |
| end() 條件 | 無右/左兄弟 | 回溯至根仍無兄弟 |
葉子遍歷迭代器展示了順序存儲樹結構支援**跨層級非線性遍歷**的能力:以 root_ 界定子樹邊界,結合向下尋找最左/最右葉子與向上回溯尋找下一分支的索引運算,實現標準雙向迭代器語意。此模式可泛化至前序、後序、層序等任意深度優先遍歷器的實現。