问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

在线索二叉树中找前驱后继

创作时间:
作者:
@小白创作中心

在线索二叉树中找前驱后继

引用
CSDN
1.
https://blog.csdn.net/m0_64055811/article/details/137911804

在线索二叉树中,每个节点除了左右子节点指针外,还增加了两个标记位:ltag和rtag。其中,ltag表示左子节点是否为前驱,rtag表示右子节点是否为后继。通过这两个标记位,我们可以方便地找到任意节点的前驱和后继节点。

一、前驱节点的查找

1. 中序线索二叉树:

在中序线索二叉树中,如果一个节点的左子节点为空,则它的前驱节点就是它的左子节点;否则,我们需要沿着左子节点一直向下遍历,直到找到一个节点的右子节点为空,那么这个节点就是前驱节点。

代码实现:

ThreadedNode* inPredecessor(ThreadedNode* p) {
    if (p->ltag == 0) { // 如果左子节点不为空,则直接返回左子节点
        return p->left;
    } else { // 否则,沿着左子节点一直向下遍历,直到找到一个节点的右子节点为空
        ThreadedNode* q = p->left;
        while (q->rtag == 1) {
            q = q->right;
        }
        return q;
    }
}

2. 前序线索二叉树:

在前序线索二叉树中,如果一个节点的左子节点为空,则它的前驱节点就是它的左子节点;否则,我们需要沿着左子节点一直向下遍历,直到找到一个节点的右子节点为空,那么这个节点就是前驱节点。

①如果能找到p的父节点且p是左孩子
②如果能找到p的父节点,且p是右孩子,其左兄弟为空
③如果能找到p的父节点,且p是右孩子,其左兄弟非空
④如果p是根节点,则p没有先序前驱

代码实现:

ThreadedNode* prePredecessor(ThreadedNode* p) {
    if (p->ltag == 0) { // 如果左子节点不为空,则直接返回左子节点
        return p->left;
    } else { // 否则,沿着左子节点一直向下遍历,直到找到一个节点的右子节点为空
        ThreadedNode* q = p->left;
        while (q->rtag == 1) {
            q = q->right;
        }
        return q;
    }
}

3. 后序线索二叉树

在后序线索二叉树中,如果一个节点的左子节点为空,则它的前驱节点就是它的左子节点;否则,我们需要沿着左子节点一直向下遍历,直到找到一个节点的右子节点为空,那么这个节点就是前驱节点。

代码实现:

ThreadedNode* postPredecessor(ThreadedNode* p) {
    if (p->ltag == 0) { // 如果左子节点不为空,则直接返回左子节点
        return p->left;
    } else { // 否则,沿着左子节点一直向下遍历,直到找到一个节点的右子节点为空
        ThreadedNode* q = p->left;
        while (q->rtag == 1) {
            q = q->right;
        }
        return q;
    }
}

二、后继节点的查找

1. 中序线索二叉树:

在中序线索二叉树中,如果一个节点的右子节点为空,则它的后继节点就是它的右子节点;否则,我们需要沿着右子节点一直向下遍历,直到找到一个节点的左子节点为空,那么这个节点就是后继节点。

代码实现:

ThreadedNode* inSuccessor(ThreadedNode* p) {
    if (p->rtag == 0) { // 如果右子节点不为空,则直接返回右子节点
        return p->right;
    } else { // 否则,沿着右子节点一直向下遍历,直到找到一个节点的左子节点为空
        ThreadedNode* q = p->right;
        while (q->ltag == 1) {
            q = q->left;
        }
        return q;
    }
}

2. 前序线索二叉树:

在前序线索二叉树中,如果一个节点的右子节点为空,则它的后继节点就是它的右子节点;否则,我们需要沿着右子节点一直向下遍历,直到找到一个节点的左子节点为空,那么这个节点就是后继节点。

代码实现:

ThreadedNode* preSuccessor(ThreadedNode* p) {
    if (p->rtag == 0) { // 如果右子节点不为空,则直接返回右子节点
        return p->right;
    } else { // 否则,沿着右子节点一直向下遍历,直到找到一个节点的左子节点为空
        ThreadedNode* q = p->right;
        while (q->ltag == 1) {
            q = q->left;
        }
        return q;
    }
}

3. 后序线索二叉树:

在后序线索二叉树中,如果一个节点的右子节点为空,则它的后继节点就是它的右子节点;否则,我们需要沿着右子节点一直向下遍历,直到找到一个节点的左子节点为空,那么这个节点就是后继节点。

①如果能找到p的父节点,且p是右孩子
②如果能找到p 的父节点,且p是左孩子,其右兄弟为空
③如果能找到p的父节点,且p是左孩子,其右兄弟非空
④如果p是根节点,则p没有后序后继

代码实现:

ThreadedNode* postSuccessor(ThreadedNode* p) {
    if (p->rtag == 0) { // 如果右子节点不为空,则直接返回右子节点
        return p->right;
    } else { // 否则,沿着右子节点一直向下遍历,直到找到一个节点的左子节点为空
        ThreadedNode* q = p->right;
        while (q->ltag == 1) {
            q = q->left;
        }
        return q;
    }
}

本文原文来自CSDN

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号