使用堆栈将三元表达式转换为二叉树
给定一个字符串str ,其中包含一个可以嵌套的三元表达式。任务是将给定的三元表达式转换为二叉树并返回根。
例子:
Input: str = "a?b:c"
Output: a b c
a
/ \
b c
The preorder traversal of the above tree is a b c.
Input: str = "a?b?c:d:e"
Output: a b c d e
a
/ \
b e
/ \
c d
方法:这是针对给定问题的基于堆栈的方法。由于三元运算符具有从右到左的结合性,因此可以从右到左遍历字符串。跳过字母'?和 ':' 因为这些字母用于决定当前字母(字母 [a 到 z])是进入堆栈还是用于从堆栈顶部弹出顶部 2 个元素以使它们成为当前字母,然后将其本身推入堆栈。这以自下而上的方式形成树,处理整个字符串后堆栈中的最后一个剩余元素是树的根。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Node structure
struct Node {
char data;
Node *left, *right;
};
// Function to create a new node
Node* createNewNode(int data)
{
Node* node = new Node;
node->data = data;
node->left = NULL, node->right = NULL;
return node;
}
// Function to print the preorder
// traversal of the tree
void preorder(Node* root)
{
if (root == NULL)
return;
cout << root->data << " ";
preorder(root->left);
preorder(root->right);
}
// Function to convert the expression to a binary tree
Node* convertExpression(string str)
{
stack s;
// If the letter is the last letter of
// the string or is of the type :letter: or ?letter:
// we push the node pointer containing
// the letter to the stack
for (int i = str.length() - 1; i >= 0;) {
if ((i == str.length() - 1)
|| (i != 0 && ((str[i - 1] == ':'
&& str[i + 1] == ':')
|| (str[i - 1] == '?'
&& str[i + 1] == ':')))) {
s.push(createNewNode(str[i]));
}
// If we do not push the current letter node to stack,
// it means the top 2 nodes in the stack currently are the
// left and the right children of the current node
// So pop these elements and assign them as the
// children of the current letter node and then
// push this node into the stack
else {
Node* lnode = s.top();
s.pop();
Node* rnode = s.top();
s.pop();
Node* node = createNewNode(str[i]);
node->left = lnode;
node->right = rnode;
s.push(node);
}
i -= 2;
}
// Finally, there will be only 1 element
// in the stack which will be the
// root of the binary tree
return s.top();
}
// Driver code
int main()
{
string str = "a?b?c:d:e";
// Convert expression
Node* root = convertExpression(str);
// Print the preorder traversal
preorder(root);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
public class Main
{
// Class containing left and
// right child of current
// node and key value
static class Node {
public char data;
public Node left, right;
public Node(char data)
{
this.data = data;
left = right = null;
}
}
// Function to create a new node
static Node createNewNode(char data)
{
Node node = new Node(data);
return node;
}
// Function to print the preorder
// traversal of the tree
static void preorder(Node root)
{
if (root == null)
return;
System.out.print(root.data + " ");
preorder(root.left);
preorder(root.right);
}
// Function to convert the expression to a binary tree
static Node convertExpression(String str)
{
Stack s = new Stack();
// If the letter is the last letter of
// the string or is of the type :letter: or ?letter:
// we push the node pointer containing
// the letter to the stack
for (int i = str.length() - 1; i >= 0😉 {
if ((i == str.length() - 1)
|| (i != 0 && ((str.charAt(i - 1) == ':'
&& str.charAt(i + 1) == ':')
|| (str.charAt(i - 1) == '?'
&& str.charAt(i + 1) == ':')))) {
s.push(createNewNode(str.charAt(i)));
}
// If we do not push the current
// letter node to stack,
// it means the top 2 nodes in
// the stack currently are the
// left and the right children of the current node
// So pop these elements and assign them as the
// children of the current letter node and then
// push this node into the stack
else {
Node lnode = (Node)s.peek();
s.pop();
Node rnode = (Node)s.peek();
s.pop();
Node node = createNewNode(str.charAt(i));
node.left = lnode;
node.right = rnode;
s.push(node);
}
i -= 2;
}
// Finally, there will be only 1 element
// in the stack which will be the
// root of the binary tree
return (Node)s.peek();
}
// Driver code
public static void main(String[] args)
{
String str = "a?b?c:d:e";
// Convert expression
Node root = convertExpression(str);
// Print the preorder traversal
preorder(root);
}
}
// This code is contributed by divyesh072019.
Python3
# Python3 implementation of the approach
# Tree Structure
class Node:
# Constructor to set the data of
# the newly created tree node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Function to create a new node
def createNewNode(data):
node = Node(data)
return node
# Function to print the preorder
# traversal of the tree
def preorder(root):
if (root == None):
return
print(root.data, end = " ")
preorder(root.left)
preorder(root.right)
# Function to convert the expression to a binary tree
def convertExpression(Str):
s = []
# If the letter is the last letter of
# the string or is of the type :letter: or ?letter:
# we push the node pointer containing
# the letter to the stack
i = len(Str) - 1
while i >= 0:
if ((i == len(Str) - 1) or (i != 0 and ((Str[i - 1] == ':' and Str[i + 1] == ':')
or (Str[i - 1] == '?' and Str[i + 1] == ':')))):
s.append(createNewNode(Str[i]))
# If we do not push the current
# letter node to stack,
# it means the top 2 nodes in
# the stack currently are the
# left and the right children of the current node
# So pop these elements and assign them as the
# children of the current letter node and then
# push this node into the stack
else:
lnode = s[-1]
s.pop()
rnode = s[-1]
s.pop()
node = createNewNode(Str[i])
node.left = lnode
node.right = rnode
s.append(node)
i -= 2
# Finally, there will be only 1 element
# in the stack which will be the
# root of the binary tree
return s[-1]
Str = "a?b?c:d:e"
# Convert expression
root = convertExpression(Str)
# Print the preorder traversal
preorder(root)
# This code is contributed by divyeshrabadiya07.
C#
// C# implementation of the approach
using System;
using System.Collections;
class GFG {
// Class containing left and
// right child of current
// node and key value
class Node {
public char data;
public Node left, right;
public Node(char data)
{
this.data = data;
left = right = null;
}
}
// Function to create a new node
static Node createNewNode(char data)
{
Node node = new Node(data);
return node;
}
// Function to print the preorder
// traversal of the tree
static void preorder(Node root)
{
if (root == null)
return;
Console.Write(root.data + " ");
preorder(root.left);
preorder(root.right);
}
// Function to convert the expression to a binary tree
static Node convertExpression(string str)
{
Stack s = new Stack();
// If the letter is the last letter of
// the string or is of the type :letter: or ?letter:
// we push the node pointer containing
// the letter to the stack
for (int i = str.Length - 1; i >= 0;) {
if ((i == str.Length - 1)
|| (i != 0 && ((str[i - 1] == ':'
&& str[i + 1] == ':')
|| (str[i - 1] == '?'
&& str[i + 1] == ':')))) {
s.Push(createNewNode(str[i]));
}
// If we do not push the current
// letter node to stack,
// it means the top 2 nodes in
// the stack currently are the
// left and the right children of the current node
// So pop these elements and assign them as the
// children of the current letter node and then
// push this node into the stack
else {
Node lnode = (Node)s.Peek();
s.Pop();
Node rnode = (Node)s.Peek();
s.Pop();
Node node = createNewNode(str[i]);
node.left = lnode;
node.right = rnode;
s.Push(node);
}
i -= 2;
}
// Finally, there will be only 1 element
// in the stack which will be the
// root of the binary tree
return (Node)s.Peek();
}
static void Main() {
string str = "a?b?c:d:e";
// Convert expression
Node root = convertExpression(str);
// Print the preorder traversal
preorder(root);
}
}
// This code is contributed by decode2207.
Javascript
输出:
a b c d e
时间复杂度: O(n)