找到二叉树的后继节点(或前驱节点)

二叉树的后继节点(或前驱节点)

文章目录

  • 二叉树的后继节点(或前驱节点)
    • 后继结点的定义
    • 二叉树节点的类型
    • 查找二叉树的后继节点
      • 代码
    • 找到二叉树的前驱节点
      • 代码

后继结点的定义

在二叉树的中序遍历中,一个节点的后继结点就是他的下一个节点

二叉树节点的类型

想要找到任意一个节点的后继结点,二叉树的节点类型Node需要包含父节点的信息

//节点
struct Node {
    int value;
    Node* parent;
    Node* left;
    Node* right;

    Node(int v = 0): value(v), parent(nullptr), left(nullptr), right(nullptr) {}
};

查找二叉树的后继节点

  • 如果当前节点current有右子树,那么右子树的最左节点就是current的后继结点
  • 如果当前节点current没有右子树,当current节点等于其父节点的左节点,current父节点就是current的后继结点

代码

#include 
#include 

//节点
struct Node {
    int value;
    Node* parent;
    Node* left;
    Node* right;

    Node(int v = 0): value(v), parent(nullptr), left(nullptr), right(nullptr) {}
};

void insert_tree(Node* &root, int value);
void insert(Node* &root, Node* &next, int value) {
    if (nullptr == next) {
        next = new Node(value);
        next->parent = root;
        return;
    }
    if (value < root->value) {
        insert_tree(root->left, value);
    } else if (value > root->value) {
        insert_tree(root->right, value);
    }
}

//向二叉树插入元素
void insert_tree(Node* &root, int value) {
    if (value < root->value) {
        insert(root, root->left, value);
    } else if (value > root->value) {
        insert(root, root->right, value);
    }
}

//生成二叉树
void create_tree(Node* root, int root_value, int size) {
    root->value = root_value++;
    for (int i = 0; i <= size; ++i) {
        insert_tree(root, i);
    }
}

//销毁二叉树
void destroy_tree(Node* root) {
    if (root == nullptr) {
        return;
    }

    destroy_tree(root->left);
    destroy_tree(root->right);

    delete root;
}

//找到最左侧节点
Node* get_most_left(Node* node) {
    while (node->left != nullptr) {
        node = node->left;
    }
    return node;
}

//找到后继节点
Node* get_successor(Node* node) {
    //右子树不为空,找到右子树最左边节点,就是node的后继节点
    if (node->right != nullptr) {
        return get_most_left(node->right);
    } else {
        //右子树为空,判断node是否等于parent->left
        Node* p = node->parent;
        while (node != p->left && p != nullptr) {
            node = p;
            p = node->parent;
        }
        return p;
    }
    return nullptr;
}

int main(void)
{
    Node* root = new Node();
    create_tree(root, 5, 9);
    auto n = get_successor(root->right->right->right);
    if (n != nullptr) {
        std::cout << n->value << std::endl;
    } else {
        std::cout << "nullptr" << std::endl;
    }

    destroy_tree(root);
    return 0;
}

找到二叉树的前驱节点

  • 右子树不为空,找到右子树最左边节点,就是node的后继节点
  • 右子树为空,判断node是否等于parent->left,如果为真,那么parent节点就是前驱结点

代码

//找到后继节点
Node* get_successor(Node* node) {
    //右子树不为空,找到右子树最左边节点,就是node的后继节点
    if (node->right != nullptr) {
        return get_most_left(node->right);
    } else {
        //右子树为空,判断node是否等于parent->left
        Node* p = node->parent;
        while (node != p->left && p != nullptr) {
            node = p;
            p = node->parent;
        }
        return p;
    }
    return nullptr;
}

你可能感兴趣的:(二叉树,数据结构,算法)