线索二叉树
简介(Introduction)
线索二叉树充分可以的利用各个节点的左右指针, 让各个节点可以指向自己的前后节点
对于二叉树的一个结点,查找其左右节点是方便的,其前驱后继只有在遍历中得到
描述(Description)
- \(n\) 个结点的二叉链表中含有共有 \(2n\) 个指针域,其中以使用 \(n - 1\) 个指针域,还有 \(n + 1\) 个空指针域
- 利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索")
- 一个结点的前一个结点,称为 前驱 结点
- 一个结点的后一个结点,称为 后继 结点
- 存储结构
\[\begin{array}[b] {|c|c|} \hline name &\ \ \ \ \ left\ \ \ \ \ &\ \ \ \ \ ltag\ \ \ \ \ &\ \ \ \ \ data\ \ \ \ \ &\ \ \ \ \ rtag\ \ \ \ \ \ &\ \ \ \ \ right \ \ \ \ \ \\ \hline\ \ \ \ type\ \ \ \ &Tree*&int &int&int &Tree* \\ \hline \end{array}\\
\]
Hints: \(l/rtag == 0\) 表示 \(left/right\) 指针指向左/右孩子,\(l/rtag == 1\) 表示 \(left/right\) 指针指向前驱/后继节点
示例(Example)
代码(Code)
- 中序构建
// C++ Version Tree *pre = NULL; // 全局变量声明 void inorder_thread(Tree *root) { if (!root) return ; inorder_thread(root->left); if (!root->left) { root->ltag = 1; root->left = pre; } if (pre && !pre->right) { pre->rtag = 1; pre->right = root; } pre = root; inorder_thread(root->right); }
-
中序找后继
// C++ Version Tree* find_inorder_next(Tree *root) { if (root->rtag) return root->right; else { // 找到右子树最左边的点,为后继节点 root = root->right; while (root->ltag) root = root->left; return root; } }
-
中序找前驱
// C++ Version Tree* find_inorder_prev(Tree *root) { if (root->ltag) return root->left; else { // 左子树的最右边节点 root = root->left; while (root->rtag) root = root->right; return root; } }