按照从 X 开始的给定模式获取二叉树的最后一个节点
给定二叉树、目标节点X和字符串patt 。任务是按照从X开始的模式找到二叉树的最后一个节点。模式只能包含五种类型的字符'p' 、 'l' 、 'r' 、 'm'和'n' 。对于遇到的任何字符:
- p:获取当前节点的父节点。
- l:获取当前节点的左孩子。
- r:获取当前节点的右孩子。
- m:到同级的左兄弟。
- n:在同一关卡中找到正确的兄弟姐妹。
请注意,如果节点不存在对应于任何字符,则跳过该字符并保留在当前节点上。
例子:
Input:
10
/ \
12 13
/ \
14 15
/ \ / \
21 22 23 24
X = 14, patt = "npmrprrlm"
Output: 22
Starting from the target node 14
n: 14 -> 15
p: 15 -> 13
m: 13 -> 12
r: 12 -> 12 (there is no right child)
p: 12 -> 10
r: 10 -> 13
r: 13 -> 15
l: 15 -> 23
m: 23 -> 22
Input:
5
/ \
16 8
X = 16, patt = "pppp"
Output: 5
方法:
- 从原始树创建一个辅助树,但包括三个额外的指针(父指针、左右兄弟指针)。
- 父指针将指向当前节点的父节点。
- 左指针将指向左兄弟。
- 右指针将指向右兄弟。
- 检查上图:
- 创建这棵树后,我们可以轻松地遍历给定的模式。
- 如果任何节点不存在对应于任何字符,则只需跳过该字符。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// A Tree node
struct Node
{
int key;
struct Node *left, *right;
};
// Utility function to create a new node
Node* newNode(int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}
struct auxNode
{
int key;
auxNode *left, *right, *parent;
// Pointer will point the left node
// at the same level in the tree
auxNode* llNode;
// Pointer will point the right node
// at the same level in the tree
auxNode* rlNode;
};
auxNode* newAuxNode(int key)
{
auxNode* temp = new auxNode;
temp->key = key;
temp->left = temp->right = temp->parent
= temp->llNode = temp->rlNode = NULL;
return temp;
}
// Function to create the auxiliary tree
auxNode* createAuxTree(Node* root)
{
if (root == NULL)
return NULL;
auxNode* auxTree = newAuxNode(root->key);
auxTree->left = createAuxTree(root->left);
auxTree->right = createAuxTree(root->right);
return auxTree;
}
// Function for arranging the parent node for every node
void makeParentNodePoint(auxNode* auxTree,
auxNode* prev_ptr)
{
if (auxTree == NULL)
return;
// Set the parent
if (prev_ptr != NULL)
{
auxTree->parent = prev_ptr;
}
// Recur for left and right sub-trees
makeParentNodePoint(auxTree->left, auxTree);
makeParentNodePoint(auxTree->right, auxTree);
}
// Function for arranging the left and right
// node for every node at the same level
void makeSameLevelNodePoint(auxNode* auxTree)
{
queue qu;
qu.push(auxTree);
while (!qu.empty())
{
int qsize = qu.size();
while (qsize--)
{
auxNode* top_ele;
top_ele = qu.front();
qu.pop();
if (qsize)
{
top_ele->rlNode = qu.front();
qu.front()->llNode = top_ele;
}
if (top_ele->left != NULL)
{
qu.push(top_ele->left);
}
if (top_ele->right != NULL)
{
qu.push(top_ele->right);
}
}
}
}
// Function to return the target node address
auxNode* getTargetNodeAddress(auxNode* auxTree, int tNode)
{
if (auxTree == NULL)
return NULL;
if (auxTree->key == tNode)
{
return auxTree;
}
auxNode* is_null = getTargetNodeAddress(auxTree->left, tNode);
if (is_null != NULL)
return is_null;
return getTargetNodeAddress(auxTree->right, tNode);
}
// Utility function to print the last node
void printNode(auxNode* auxTree,
auxNode* target_node,
string pattern)
{
// Perform the movement
for (int i = 0; i < pattern.length(); i++)
{
switch (pattern[i])
{
// Get to the parent
case 'p':
case 'P':
if (target_node->parent != NULL)
{
target_node = target_node->parent;
}
break;
// Get to the left child
case 'l':
case 'L':
if (target_node->left != NULL)
{
target_node = target_node->left;
}
break;
// Get to the right child
case 'r':
case 'R':
if (target_node->right != NULL)
target_node = target_node->right;
break;
// Get to the left sibling in the same level
case 'm':
case 'M':
if (target_node->llNode != NULL)
target_node = target_node->llNode;
break;
// Get to the right sibling in the same level
case 'n':
case 'N':
if (target_node->rlNode != NULL)
target_node = target_node->rlNode;
break;
default:
return;
}
}
cout << target_node->key;
}
// Function to print the last node
// according to the pattern
void printNodeUsingPattern(Node* root,
string pattern, int tNode)
{
// Function will create auxiliary tree same as
// original tree with left child and right child
auxNode* auxTree = createAuxTree(root);
// Function will make every node
// point to its parent node
makeParentNodePoint(auxTree, NULL);
// Function will make every node point to its
// left and right node at the same level
makeSameLevelNodePoint(auxTree);
// Function will give the address of the target node
auxNode* target_node = getTargetNodeAddress(auxTree, tNode);
// If target node found
if (target_node != NULL)
{
// Function call to print the last node
// according to the given pattern
printNode(auxTree, target_node, pattern);
}
else
cout << "-1";
}
// Driver code
int main()
{
Node* root = newNode(10);
root->left = newNode(12);
root->right = newNode(13);
root->right->left = newNode(14);
root->right->right = newNode(15);
root->right->left->left = newNode(21);
root->right->left->right = newNode(22);
root->right->right->left = newNode(23);
root->right->right->right = newNode(24);
int target_node = 14;
string str = "npmrprrlm";
printNodeUsingPattern(root, str, target_node);
return 0;
}
Python3
# Python3 implementation of the approach
import queue
# A Tree node
class Node:
def __init__(self,key):
self.left = None
self.right = None
self.key = key
class auxNode:
def __init__(self,key):
self.left = None
self.right = None
self.key = key
self.parent = None
# Pointer will point the left node
# at the same level in the tree
self.llNode = None
# Pointer will point the right node
# at the same level in the tree
self.rlNode = None
def newAuxNode(key):
temp = auxNode(key)
return temp
def createAuxTree(root):
if (root == None) :
return None
auxTree = auxNode(root.key)
auxTree.left = createAuxTree(root.left)
auxTree.right = createAuxTree(root.right)
return auxTree
# Function for arranging the
# parent node for every node
def makeParentNodePoint(auxTree, prev_ptr):
if (auxTree == None):
return;
# Set the parent
if (prev_ptr != None) :
auxTree.parent = prev_ptr
#print("Parent : ",auxTree.parent.key)
# Recur for left and right sub-trees
makeParentNodePoint(auxTree.left, auxTree)
makeParentNodePoint(auxTree.right, auxTree)
# Function for arranging the left and right
# node for every node at the same level
def makeSameLevelNodePoint(auxTree):
qu = queue.Queue(maxsize = 50)
qu.put(auxTree)
while (not qu.empty()) :
size = qu.qsize()
while (size) :
size -= 1
top_ele = qu.get();
if (size) :
front = qu.get()
top_ele.rlNode = front
front.llNode = top_ele
# since we don't have peek function
# in python creating 2nd queue
# to store elements below peek element
qu2 = queue.Queue(maxsize = 50)
while not qu.empty():
a = qu.get()
qu2.put(a)
# putting back front element
# in queue 1 all elements which
# were behind it in original queue
qu.put(front)
while not qu2.empty():
qu.put(qu2.get())
if (top_ele.left != None) :
qu.put(top_ele.left)
if (top_ele.right != None) :
qu.put(top_ele.right)
# Function to return the target node address
def getTargetNodeAddress(auxTree, tNode):
if (auxTree == None):
return None
if (auxTree.key == tNode) :
return auxTree
is_null = getTargetNodeAddress(auxTree.left, tNode)
if (is_null != None):
return is_null
return getTargetNodeAddress(auxTree.right, tNode)
# Utility function to print the last node
def printNode(auxTree, target_node, pattern):
# Perform the movement
for i in range(len(pattern)) :
# Get to the parent
if pattern[i] == 'p' or pattern[i] == 'P':
if (target_node.parent != None):
target_node = target_node.parent
# Get to the left child
elif pattern[i] == 'l' or pattern[i] == 'L':
if (target_node.left != None) :
target_node = target_node.left
# Get to the right child
elif pattern[i] == 'r' or pattern[i] == 'R':
if (target_node.right != None):
target_node = target_node.right
# Get to the left sibling in the same level
elif pattern[i] == 'm' or pattern[i] == 'M':
if (target_node.llNode != None):
target_node = target_node.llNode
# Get to the right sibling in the same level
elif pattern[i] == 'n' or pattern[i] == 'N':
if (target_node.rlNode != None):
target_node = target_node.rlNode
else:
return
print(target_node.key, end = ' ')
# Function to print the last node
# according to the pattern
def printNodeUsingPattern(root, pattern, tNode):
# Function will create auxiliary tree same as
# original tree with left child and right child
auxTree = createAuxTree(root)
# Function will make every node
# point to its parent node
makeParentNodePoint(auxTree, None)
# Function will make every node point to its
# left and right node at the same level
makeSameLevelNodePoint(auxTree)
# Function will give the address of the target node
target_node = getTargetNodeAddress(auxTree, tNode)
# If target node found
if (target_node != None) :
# Function call to print the last node
# according to the given pattern
printNode(auxTree, target_node, pattern);
else :
print("-1")
# Driver Code
root = Node(10)
root.left = Node(12)
root.right = Node(13)
root.right.left = Node(14)
root.right.right = Node(15)
root.right.left.left = Node(21)
root.right.left.right = Node(22)
root.right.right.left = Node(23)
root.right.right.right = Node(24)
target_node = 14
string = "npmrprrlm"
printNodeUsingPattern(root, string, target_node)
# This code is contributed by Sadik Ali
Javascript
输出:
22