线索二叉树

简介(Introduction)

线索二叉树充分可以的利用各个节点的左右指针, 让各个节点可以指向自己的前后节点
对于二叉树的一个结点,查找其左右节点是方便的,其前驱后继只有在遍历中得到


描述(Description)

  1. \(n\) 个结点的二叉链表中含有共有 \(2n\) 个指针域,其中以使用 \(n - 1\) 个指针域,还有 \(n + 1\) 个空指针域
  2. 利用二叉链表中的空指针域,存放指向该结点在某种遍历次序下的前驱和后继结点的指针(这种附加的指针称为"线索")
  3. 一个结点的前一个结点,称为 前驱 结点
  4. 一个结点的后一个结点,称为 后继 结点

  • 存储结构

\[\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)

image


代码(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;
    	}
    }
    

posted @ 2023-05-02 23:24  FFex  阅读(8)  评论(0编辑  收藏  举报