二叉搜索树中节点的后序前驱
给定一棵二叉树和二叉树中的一个节点,找到给定节点的后序前驱。
例子:
Consider the following binary tree
20
/ \
10 26
/ \ / \
4 18 24 27
/ \
14 19
/ \
13 15
Input : 4
Output : 10
Postorder traversal of given tree is 4, 13, 15,
14, 19, 18, 10, 24, 27, 26, 20.
Input : 24
Output : 10
一个简单的解决方案是首先将给定树的后序遍历存储在一个数组中,然后线性搜索给定节点并打印它旁边的节点。
时间复杂度:O(n)
辅助空间:O(n)
一个有效的解决方案基于以下观察。
- 如果给定节点的右孩子存在,那么右孩子就是后序前任。
- 如果右子节点不存在并且给定节点是其父节点的左子节点,则其兄弟节点是其后序前辈。
- 如果以上条件都不满足(左子节点不存在且给定节点不是其父节点的右子节点),则我们使用父指针向上移动,直到发生以下情况之一。
- 我们到达了根源。在这种情况下,Postorder 前驱不存在。
- 当前节点(给定节点的祖先之一)是其父节点的右子节点,在这种情况下,后序前驱节点是当前节点的兄弟节点。
C++
// C++ program to find postorder predecessor of
// a node in Binary Tree.
#include
using namespace std;
struct Node {
struct Node *left, *right, *parent;
int key;
};
Node* newNode(int key)
{
Node* temp = new Node;
temp->left = temp->right = temp->parent = NULL;
temp->key = key;
return temp;
}
Node* postorderPredecessor(Node* root, Node* n)
{
// If right child exists, then it is postorder
// predecessor.
if (n->right)
return n->right;
// If right child does not exist, then
// travel up (using parent pointers)
// until we reach a node which is right
// child of its parent.
Node *curr = n, *parent = curr->parent;
while (parent != NULL && parent->left == curr) {
curr = curr->parent;
parent = parent->parent;
}
// If we reached root, then the given
// node has no postorder predecessor
if (parent == NULL)
return NULL;
return parent->left;
}
int main()
{
Node* root = newNode(20);
root->parent = NULL;
root->left = newNode(10);
root->left->parent = root;
root->left->left = newNode(4);
root->left->left->parent = root->left;
root->left->right = newNode(18);
root->left->right->parent = root->left;
root->right = newNode(26);
root->right->parent = root;
root->right->left = newNode(24);
root->right->left->parent = root->right;
root->right->right = newNode(27);
root->right->right->parent = root->right;
root->left->right->left = newNode(14);
root->left->right->left->parent = root->left->right;
root->left->right->left->left = newNode(13);
root->left->right->left->left->parent = root->left->right->left;
root->left->right->left->right = newNode(15);
root->left->right->left->right->parent = root->left->right->left;
root->left->right->right = newNode(19);
root->left->right->right->parent = root->left->right;
Node* nodeToCheck = root->left->right;
Node* res = postorderPredecessor(root, nodeToCheck);
if (res) {
printf("Postorder predecessor of %d is %d\n",
nodeToCheck->key, res->key);
}
else {
printf("Postorder predecessor of %d is NULL\n",
nodeToCheck->key);
}
return 0;
}
Java
// Java program to find postorder predecessor
// of a node in Binary Tree.
import java.util.*;
class GFG{
static class Node
{
Node left, right, parent;
int key;
};
static Node newNode(int key)
{
Node temp = new Node();
temp.left = temp.right = temp.parent = null;
temp.key = key;
return temp;
}
static Node postorderPredecessor(Node root, Node n)
{
// If right child exists, then it is
// postorder predecessor.
if (n.right != null)
return n.right;
// If right child does not exist, then
// travel up (using parent pointers)
// until we reach a node which is right
// child of its parent.
Node curr = n, parent = curr.parent;
while (parent != null && parent.left == curr)
{
curr = curr.parent;
parent = parent.parent;
}
// If we reached root, then the given
// node has no postorder predecessor
if (parent == null)
return null;
return parent.left;
}
// Driver code
public static void main(String[] args)
{
Node root = newNode(20);
root.parent = null;
root.left = newNode(10);
root.left.parent = root;
root.left.left = newNode(4);
root.left.left.parent = root.left;
root.left.right = newNode(18);
root.left.right.parent = root.left;
root.right = newNode(26);
root.right.parent = root;
root.right.left = newNode(24);
root.right.left.parent = root.right;
root.right.right = newNode(27);
root.right.right.parent = root.right;
root.left.right.left = newNode(14);
root.left.right.left.parent = root.left.right;
root.left.right.left.left = newNode(13);
root.left.right.left.left.parent = root.left.right.left;
root.left.right.left.right = newNode(15);
root.left.right.left.right.parent = root.left.right.left;
root.left.right.right = newNode(19);
root.left.right.right.parent = root.left.right;
Node nodeToCheck = root.left.right;
Node res = postorderPredecessor(root, nodeToCheck);
if (res != null)
{
System.out.printf("Postorder predecessor " +
"of %d is %d\n",
nodeToCheck.key, res.key);
}
else
{
System.out.printf("Postorder predecessor " +
"of %d is null\n",
nodeToCheck.key);
}
}
}
// This code is contributed by Rajput-Ji
Python3
"""Python3 program to find postorder
predecessor of given node."""
# A Binary Tree Node
# Utility function to create a
# new tree node
class newNode:
# Constructor to create a newNode
def __init__(self, data):
self.key = data
self.left = None
self.right = self.parent = None
def postorderPredecessor(root, n):
# If right child exists, then it
# is postorder predecessor.
if (n.right) :
return n.right
# If right child does not exist, then
# travel up (using parent pointers)
# until we reach a node which is right
# child of its parent.
curr = n
parent = curr.parent
while (parent != None and
parent.left == curr):
curr = curr.parent
parent = parent.parent
# If we reached root, then the given
# node has no postorder predecessor
if (parent == None) :
return None
return parent.left
# Driver Code
if __name__ == '__main__':
root = newNode(20)
root.parent = None
root.left = newNode(10)
root.left.parent = root
root.left.left = newNode(4)
root.left.left.parent = root.left
root.left.right = newNode(18)
root.left.right.parent = root.left
root.right = newNode(26)
root.right.parent = root
root.right.left = newNode(24)
root.right.left.parent = root.right
root.right.right = newNode(27)
root.right.right.parent = root.right
root.left.right.left = newNode(14)
root.left.right.left.parent = root.left.right
root.left.right.left.left = newNode(13)
root.left.right.left.left.parent = root.left.right.left
root.left.right.left.right = newNode(15)
root.left.right.left.right.parent = root.left.right.left
root.left.right.right = newNode(19)
root.left.right.right.parent = root.left.right
nodeToCheck = root.left.right
res = postorderPredecessor(root, nodeToCheck)
if (res) :
print("Postorder predecessor of",
nodeToCheck.key, "is", res.key)
else:
print("Postorder predecessor of",
nodeToCheck.key, "is None")
# This code is contributed
# by SHUBHAMSINGH10
C#
// C# program to find postorder
// predecessor of a node
// in Binary Tree.
using System;
class GFG{
class Node
{
public Node left, right, parent;
public int key;
};
static Node newNode(int key)
{
Node temp = new Node();
temp.left = temp.right =
temp.parent = null;
temp.key = key;
return temp;
}
static Node postorderPredecessor(Node root,
Node n)
{
// If right child exists,
// then it is postorder
// predecessor.
if (n.right != null)
return n.right;
// If right child does not exist, then
// travel up (using parent pointers)
// until we reach a node which is right
// child of its parent.
Node curr = n, parent = curr.parent;
while (parent != null &&
parent.left == curr)
{
curr = curr.parent;
parent = parent.parent;
}
// If we reached root, then the given
// node has no postorder predecessor
if (parent == null)
return null;
return parent.left;
}
// Driver code
public static void Main(String[] args)
{
Node root = newNode(20);
root.parent = null;
root.left = newNode(10);
root.left.parent = root;
root.left.left = newNode(4);
root.left.left.parent = root.left;
root.left.right = newNode(18);
root.left.right.parent = root.left;
root.right = newNode(26);
root.right.parent = root;
root.right.left = newNode(24);
root.right.left.parent = root.right;
root.right.right = newNode(27);
root.right.right.parent = root.right;
root.left.right.left = newNode(14);
root.left.right.left.parent = root.left.right;
root.left.right.left.left = newNode(13);
root.left.right.left.left.parent = root.left.right.left;
root.left.right.left.right = newNode(15);
root.left.right.left.right.parent = root.left.right.left;
root.left.right.right = newNode(19);
root.left.right.right.parent = root.left.right;
Node nodeToCheck = root.left.right;
Node res = postorderPredecessor(root, nodeToCheck);
if (res != null)
{
Console.Write("Postorder predecessor " +
"of {0} is {1}\n",
nodeToCheck.key, res.key);
}
else
{
Console.Write("Postorder predecessor " +
"of {0} is null\n",
nodeToCheck.key);
}
}
}
// This code is contributed by shikhasingrajput
Javascript
输出:
Postorder predecessor of 18 is 19
时间复杂度: O(h) 其中 h 是给定二叉树的高度
辅助空间: O(1)