📜  用父指针查找二叉树的右兄弟

📅  最后修改于: 2022-05-13 01:57:16.607000             🧑  作者: Mango

用父指针查找二叉树的右兄弟

给定具有父指针的二叉树,找到给定节点的右兄弟(将给出指向该节点的指针),如果不存在则返回 null。在 O(1) 空间和 O(n) 时间内完成吗?
例子:

1
            / \
           2   3
          /  \  \
         4    6  5
        /      \  \
       7        9  8
       /         \
      10         12
Input : Given above tree with parent pointer and node 10
Output : 12 

方法:这个想法是找出最近的祖先的第一个右孩子,它既不是当前节点也不是当前节点的父节点,在上升的同时跟踪那些级别。然后,遍历该节点的第一个左子节点,如果左边不存在则为右子节点,如果级别变为 0,则这是给定节点的下一个右兄弟节点。
在上面的例子中,如果给定的节点是 7,我们最终会得到 6 来找到没有任何子节点的正确子节点。
在这种情况下,我们需要递归调用具有当前级别的右兄弟,以便我们达到 8。

C++
// C program to print right sibling of a node
#include 
 
// A Binary Tree Node
struct Node {
    int data;
    Node *left, *right, *parent;
};
 
// A utility function to create a new Binary
// Tree Node
Node* newNode(int item, Node* parent)
{
    Node* temp = new Node;
    temp->data = item;
    temp->left = temp->right = NULL;
    temp->parent = parent;
    return temp;
}
 
// Method to find right sibling
Node* findRightSibling(Node* node, int level)
{
    if (node == NULL || node->parent == NULL)
        return NULL;
 
    // GET Parent pointer whose right child is not
    // a parent or itself of this node. There might
    // be case when parent has no right child, but,
    // current node is left child of the parent
    // (second condition is for that).
    while (node->parent->right == node
           || (node->parent->right == NULL
               && node->parent->left == node)) {
        if (node->parent == NULL
            || node->parent->parent == NULL)
            return NULL;
 
        node = node->parent;
        level--;
    }
 
    // Move to the required child, where right sibling
    // can be present
    node = node->parent->right;
 
    if (node == NULL)
        return NULL;
    // find right sibling in the given subtree(from current
    // node), when level will be 0
    while (level < 0) {
 
        // Iterate through subtree
        if (node->left != NULL)
            node = node->left;
        else if (node->right != NULL)
            node = node->right;
        else
 
            // if no child are there, we cannot have right
            // sibling in this path
            break;
 
        level++;
    }
 
    if (level == 0)
        return node;
 
    // This is the case when we reach 9 node in the tree,
    // where we need to again recursively find the right
    // sibling
    return findRightSibling(node, level);
}
 
// Driver Program to test above functions
int main()
{
    Node* root = newNode(1, NULL);
    root->left = newNode(2, root);
    root->right = newNode(3, root);
    root->left->left = newNode(4, root->left);
    root->left->right = newNode(6, root->left);
    root->left->left->left = newNode(7, root->left->left);
    root->left->left->left->left = newNode(10, root->left->left->left);
    root->left->right->right = newNode(9, root->left->right);
    root->right->right = newNode(5, root->right);
    root->right->right->right = newNode(8, root->right->right);
    root->right->right->right->right = newNode(12, root->right->right->right);
 
    // passing 10
    Node* res = findRightSibling(root->left->left->left->left, 0);
    if (res == NULL)
        printf("No right sibling");
    else
        printf("%d", res->data);
 
    return 0;
}


Java
// Java program to print right sibling of a node
public class Right_Sibling {
 
    // A Binary Tree Node
    static class Node {
        int data;
        Node left, right, parent;
 
        // Constructor
        public Node(int data, Node parent)
        {
            this.data = data;
            left = null;
            right = null;
            this.parent = parent;
        }
    };
 
    // Method to find right sibling
    static Node findRightSibling(Node node, int level)
    {
        if (node == null || node.parent == null)
            return null;
 
        // GET Parent pointer whose right child is not
        // a parent or itself of this node. There might
        // be case when parent has no right child, but,
        // current node is left child of the parent
        // (second condition is for that).
        while (node.parent.right == node
               || (node.parent.right == null
                   && node.parent.left == node)) {
            if (node.parent == null)
                return null;
 
            node = node.parent;
            level--;
        }
 
        // Move to the required child, where right sibling
        // can be present
        node = node.parent.right;
 
        // find right sibling in the given subtree(from current
        // node), when level will be 0
        while (level < 0) {
 
            // Iterate through subtree
            if (node.left != null)
                node = node.left;
            else if (node.right != null)
                node = node.right;
            else
 
                // if no child are there, we cannot have right
                // sibling in this path
                break;
 
            level++;
        }
 
        if (level == 0)
            return node;
 
        // This is the case when we reach 9 node in the tree,
        // where we need to again recursively find the right
        // sibling
        return findRightSibling(node, level);
    }
 
    // Driver Program to test above functions
    public static void main(String args[])
    {
        Node root = new Node(1, null);
        root.left = new Node(2, root);
        root.right = new Node(3, root);
        root.left.left = new Node(4, root.left);
        root.left.right = new Node(6, root.left);
        root.left.left.left = new Node(7, root.left.left);
        root.left.left.left.left = new Node(10, root.left.left.left);
        root.left.right.right = new Node(9, root.left.right);
        root.right.right = new Node(5, root.right);
        root.right.right.right = new Node(8, root.right.right);
        root.right.right.right.right = new Node(12, root.right.right.right);
 
        // passing 10
        System.out.println(findRightSibling(root.left.left.left.left, 0).data);
    }
}
// This code is contributed by Sumit Ghosh


Python3
# Python3 program to print right sibling
# of a node
 
# A class to create a new Binary
# Tree Node
class newNode:
    def __init__(self, item, parent):
        self.data = item
        self.left = self.right = None
        self.parent = parent
 
# Method to find right sibling
def findRightSibling(node, level):
    if (node == None or node.parent == None):
        return None   
 
    # GET Parent pointer whose right child is not
    # a parent or itself of this node. There might
    # be case when parent has no right child, but,
    # current node is left child of the parent
    # (second condition is for that).
    while (node.parent.right == node or
          (node.parent.right == None and
           node.parent.left == node)):
        if (node.parent == None):
            return None
 
        node = node.parent
        level -= 1
 
    # Move to the required child, where
    # right sibling can be present
    node = node.parent.right
 
    # find right sibling in the given subtree
    # (from current node), when level will be 0
    while (level < 0):
 
        # Iterate through subtree
        if (node.left != None):
            node = node.left
        else if (node.right != None):
            node = node.right
        else:
 
            # if no child are there, we cannot
            # have right sibling in this path
            break
         
        level += 1
 
    if (level == 0):
        return node    
 
    # This is the case when we reach 9 node
    # in the tree, where we need to again
    # recursively find the right sibling
    return findRightSibling(node, level)
 
# Driver Code
if __name__ == '__main__':
    root = newNode(1, None)
    root.left = newNode(2, root)
    root.right = newNode(3, root)
    root.left.left = newNode(4, root.left)
    root.left.right = newNode(6, root.left)
    root.left.left.left = newNode(7, root.left.left)
    root.left.left.left.left = newNode(10, root.left.left.left)
    root.left.right.right = newNode(9, root.left.right)
    root.right.right = newNode(5, root.right)
    root.right.right.right = newNode(8, root.right.right)
    root.right.right.right.right = newNode(12, root.right.right.right)
 
    # passing 10
    res = findRightSibling(root.left.left.left.left, 0)
    if (res == None):
        print("No right sibling")
    else:
        print(res.data)
 
# This code is contributed by PranchalK


C#
using System;
 
// C# program to print right sibling of a node
public class Right_Sibling {
 
    // A Binary Tree Node
    public class Node {
        public int data;
        public Node left, right, parent;
 
        // Constructor
        public Node(int data, Node parent)
        {
            this.data = data;
            left = null;
            right = null;
            this.parent = parent;
        }
    }
 
    // Method to find right sibling
    public static Node findRightSibling(Node node, int level)
    {
        if (node == null || node.parent == null) {
            return null;
        }
 
        // GET Parent pointer whose right child is not
        // a parent or itself of this node. There might
        // be case when parent has no right child, but,
        // current node is left child of the parent
        // (second condition is for that).
        while (node.parent.right == node
               || (node.parent.right == null
                   && node.parent.left == node)) {
            if (node.parent == null
                || node.parent.parent == null) {
                return null;
            }
 
            node = node.parent;
            level--;
        }
 
        // Move to the required child, where right sibling
        // can be present
        node = node.parent.right;
 
        // find right sibling in the given subtree(from current
        // node), when level will be 0
        while (level < 0) {
 
            // Iterate through subtree
            if (node.left != null) {
                node = node.left;
            }
            else if (node.right != null) {
                node = node.right;
            }
            else {
 
                // if no child are there, we cannot have right
                // sibling in this path
                break;
            }
 
            level++;
        }
 
        if (level == 0) {
            return node;
        }
 
        // This is the case when we reach 9 node in the tree,
        // where we need to again recursively find the right
        // sibling
        return findRightSibling(node, level);
    }
 
    // Driver Program to test above functions
    public static void Main(string[] args)
    {
        Node root = new Node(1, null);
        root.left = new Node(2, root);
        root.right = new Node(3, root);
        root.left.left = new Node(4, root.left);
        root.left.right = new Node(6, root.left);
        root.left.left.left = new Node(7, root.left.left);
        root.left.left.left.left = new Node(10, root.left.left.left);
        root.left.right.right = new Node(9, root.left.right);
        root.right.right = new Node(5, root.right);
        root.right.right.right = new Node(8, root.right.right);
        root.right.right.right.right = new Node(12, root.right.right.right);
 
        // passing 10
        Console.WriteLine(findRightSibling(root.left.left.left.left, 0).data);
    }
}
 
// This code is contributed by Shrikant13


Javascript


输出:

12

时间复杂度: O(N)

辅助空间: O(1)