Expression Tree implementation issues - c++

I'm having a headache trying to build an expression tree, in particular the pointers for the treenodes, which i have no clue on how to implement and actually create the nodes to store data which is supposed to be pretty basic but the code just confuses me.
For example, when i want to create an expression of 5 + 5 this is what it should look like:
+
/ \
5 5
However when implementing this, i'm not sure how to begin. How do i get the operator in the root node and the numbers as children? I know i can store them in a stack and read off the top however the set parent, left child and right child methods only take (TreeNode *) arguments while the vector tokens are type string.
Also the constructor for the TreeNode take an integer and operator value, why is that? How can i get those values into their respective nodes as root, parent and children?
ExprTree.cpp
#include "ExprTree.h"
#include <sstream>
#include <iostream>
TreeNode * createOperatorNode(const string & op){
if (op == "+") return new TreeNode(Plus);
if (op == "-") return new TreeNode(Minus);
if (op == "*") return new TreeNode(Times);
if (op == "/") return new TreeNode(Divide);
return new TreeNode(NoOp);
}
/*
* Basic constructor that sets up an empty Expr Tree.
*/
ExprTree::ExprTree(){
this->root = NULL;
this-> _size = 0;
}
/*
* Constructor that takes a TreeNode and sets up an ExprTree with that node at the root.
*/
ExprTree::ExprTree(TreeNode * r){
this->root = r;
}
ExprTree ExprTree::buildTree(vector<string> tokens){
// the tokens are the broken up arithimec expression
i.e
5
+
5
// not sure what to do here, i've tried using stacks but i wasn't sure how to get the stored data into the nodes.
}
TreeNode.cpp
#include "TreeNode.h"
TreeNode::TreeNode(Operator o){
op = o;
parent = 0;
leftChild = 0;
rightChild = 0;
}
TreeNode::TreeNode(int val){
op = Value;
value = val;
parent = 0;
leftChild = 0;
rightChild = 0;
}
TreeNode.h
#include <string>
#include <sstream>
enum Operator {Value, Plus, Minus, Times, Divide, NoOp};
class TreeNode {
private:
Operator op; //If this node represents an operator, this is where it's stored.
//It can take values from the Operator enum (i.e. Plus, Minus, etc.)
//If it represents a value, use the Value value. :D
int value; //If this node stores an actual number, this is it.
TreeNode * parent; //Pointer to the parent.
TreeNode * leftChild; //Pointer to the left child of this node.
TreeNode * rightChild; //Pointer to the right child of this node.
public:
TreeNode(Operator); //Constructor to use for +, -, * and /.
//Example: TreeNode(Plus);
TreeNode(int); //Constructor to use for actual numbers.
//Example: TreeNode(5);
void setParent(TreeNode *); //Set the parent pointer.
void setLeftChild(TreeNode *); //Set the left child pointer.
void setRightChild(TreeNode *); //Set the right child pointer.
TreeNode * getParent(); //Get the parent pointer.
TreeNode * getLeftChild(); //Get the left child pointer.
TreeNode * getRightChild(); //Get the right child pointer.
int getValue(); //Returns the stored value;
Operator getOperator(); //Returns the stored operator.
bool isValue(); //Returns true if this node is a Value node.
bool isOperator(); //Returns truee if this node is Plus, Minus, Times or Divide node.
std::string toString(); //Returns a simple string representation of the node.
};

The easiest way of parsing expressions is to build a recursive descent parser. This consists of mutually recursive functions called expression, term, and factor. A factor is the smallest unit, either a basic number or open parentheses, expression, close parentheses (so the mutual recursion comes in). Terms are collections of factors with multiplication and divide operators, and expressions are collections of terms joined by plus and minus operators.
You need a special rule for unary minus.
Now a recursive descent parser doesn't actually build a tree as a structure in memory. The tree is implicit in the call pattern. However if you want a tree you can easily enough modify it to build one.
It might help to take a look at my very simple Basic interpreter
https://github.com/MalcolmMcLean/minibasic

You simply use what TreeNode.h gives you.
For instance, if you want to create a tree with the name root that represents 5 + 5, you go like
TreeNode root(Plus);
root.setLeftChild(new TreeNode(5));
root.setRightChild(new TreeNode(5));
Within a parser, well, try to build one. Note that you can traverse your tree easily by following children and parent pointers.
Another way would be to create a constructor over a string, which evaluates as the outermost operator and then recursively constructs it's children by giving them the appropriate substrings, like
TreeNode::TreeNode(string expression){
if(expression is number){
create this as number node
}
create this as operator node with outermost operator
split string by outermost operator
set left child to left side of split string
set right child to ...
}
That said, as a remark, I don't see ~TreeNode() being defined, which means that you will have a memory leak.
Also, I recommend to separate Tree and TreeNode, that is to create a class Tree which has TreeNode as an inner class, and that the constructor and destructor of TreeNode is private (with Tree as a friend). Gives you more control over things. Actions such as setLeftChild can be dangerous in regard to memory leaks if done incorrectly and one would be able to create loops (which defies the idea of a tree).

First, convert your expression into a postfix expression (Infix To Postfix).
Expression : 5 + 5
Postfix : 5 5 +
Then parse the postfix string and whenever you find an operand push it into a stack, or if you find an operator then pop the two operands from the stack (if it's a binary operator) and then assign the tree root as the operator the left & right child as the operands.
Tree *t;
Stack<string> stack;
// parsing the tokens(expression)...
for(int i=0; i<token[i].length(); i++) {
if(token[i] == "+" || token[i] == "-" || token[i] == "*" || token[i] == "/") {
string op1 = stack.top(); stack.pop();
string op2 = stack.top(); stack.pop();
t->root = new createOperatorNode(token[i]);
t->leftChild = new TreeNode(op1);
t->rightChild = new TreeNode(op2);
}
else {
stack.push(token[i]);
}
}

Related

Creating a function that returns a new identical binary tree and adds new nodes to all pre-existing leaves

Create a function that returns a new binary tree identical to the binary tree passed in except that every leaf in the new tree now has a left child and a right child whose values are equal to x and y.
You were close. The case that handles the expansion is correct, but you messed up the iteration a bit. Here's a possible solution:
void expand_leaf(TreeNode * node, int x, int y)
{
// recursively iterate over tree:
if (node->left) expand_leaf(node->left, x, y);
if (node->right) expand_leaf(node->right, x, y);
// expand leafes:
if (!node->left && !node->right)
{
node->left = new TreeNode(x, nullptr, nullptr);
node->right = new TreeNode(y, nullptr, nullptr);
}
}
Your problem can be elegantly decomposed into two sub-problems:
Find all leafs in the tree.
Add children x and y to leafs.
One viable way to find all leafs, is to iterate over ALL nodes of the tree and check if they are leafs (if their left/right pointers are null). This is what the first part of the above expand_leaf function does: Whenever a child pointer is present, it is recursively visited. This effectively visits all nodes of the entire tree.
Now that we have a means to visit all nodes, we can filter out the leafs. This is what the second part of the function does. Whenever we discover a leaf, we add the x/y children to it.
It is very important that the expansion happens after the recursive call. Otherwise we would end up in an infinite loop. Consider why.
Comments on original solution
The abort condition/base case is needed and mostly correct, but you create a new TreeNode prematurely. If you then discover that node==null, you overwrite the just-created n with null also, which results in a memory leak. Solution: Simplify the base case to if (node == nullptr) return nullptr; and move TreeNode * n = new TreeNode; past the if, once you know that you aren't dealing with a null node.
The rest looks functionally correct (haven't run the code). Perhaps it can be improved further for readability?
I would do it as follows:
# define KEY(p) (p->data)
# define LLINK(p) (p->left)
# define RLINK(p) (p->right)
TreeNode * expand_leaf(TreeNode * node, int x, int y)
{
if (node == nullptr)
return nullptr; // copy of empty tree is an empty tree
TreeNode * root = new TreeNode(KEY(node)); // node copy with its key
if (LLINK(node) == nullptr and RLINK(node)) // node is leaf? (this is the base case)
{ // yes ==> create children with x and y
LLINK(root) = new TreeNode(x);
RLINK(root) = new TreeNode(y);
return root;
}
LLINK(root) = expand_leaf(LLINK(node), x, y);
RLINK(root) = expand_leaf(RLINK(node), x, y);
return root;
}
For simplicity, I assume a constructor for TreeNode class which receives the key. If you have not it, then you could add an additional line for setting the key value

c++ overloading [] to print nth item of linked list

I have an assignment which involves different linked list operations. One of them involves overloading the square bracket operator to be able to print the ith element of the linked list. I have everything else done but I am really lost on this. This is what I am working with. The list class is as follows:
class List {
public:
// Creates a default empty list
List();
// Simple destructor
~List();
// Insert "data" at the very end of the list
void AddToFront(int data);
// Remove and return the first data item from the list.
int deleteFront();
// Prints the list
void Print() ;
// Returns the size of the list
unsigned int Size() const;
//overloaded assignment operator
Node operator[](unsigned int i) ;
private:
Node *m_head;
};
Also, here is my node class:
class Node {
public:
Node();
~Node();
Node(int data);
int m_data;
Node *m_next;
};
Any help on the overloading [] operator would be greatly appreciated.
Node* operator [] (int value) {
Node *temp = this->m_head;
for(int i = 0; i < value && temp!=NULL; i++) {
temp = temp->m_next;
}
return temp;
}
I assume that you want to return the node corresponding to the value specified, in the square brackets. You overload any operator using the operator keyword followed by the operator, and then the parameters passed.
For more info check this :: Operator overloading
EDIT ::
As pointed by erip and Lajos there should be a way, in case the (value > size_of_list), in that case, a possible solution would be throw an exception, which you can later catch in your program to show that value was out of bound. Or considering the current implementation, if value > size_of_list in that case temp would become NULL, so during your execution you can check if value of Node * returned is NULL or not.
A further more optimized way would be to keep a variable size_of_list in the class List, and then we can simply add an if condition to the function like this ::
if(value >= size_of_list) // equal to sign is put, considering your `size_of_list` starts from 1
return NULL;
This, would be more optimized in case of large Lists, which would avoid wasteful execution of the for loop!

temporary pointer point to a using vector address

I have a question about parsing the string s into a binary tree.
struct TreeNode {
string val; // The data in this node.
TreeNode *left; // Pointer to the left subtree.
TreeNode *right; // Pointer to the right subtree.
};
string s="((OR (AND pass (NOT reject)) (AND (NOT pass) reject)))";
I do some stroke and eliminate the "(" and ")" and keep all the separate part in vector aftersplit,
aftersplit has (bottom) OR AND pass NOT reject AND NOT pass reject (back)
vector<string> aftersplit;
vector<TreeNode> parsetree;
while (!aftersplit.empty())//do the parsing
{
TreeNode *temp=new TreeNode;
temp->val=aftersplit.back();
temp->left=NULL;
temp->right=NULL;
aftersplit.pop_back();
if(temp->val=="AND"||temp->val=="OR"||temp->val=="=>"||temp->val=="<=>"){
TreeNode *leftnode = new TreeNode;
leftnode=&parsetree.back();
parsetree.pop_back();
temp->left=leftnode;
TreeNode *rightnode = new TreeNode;
rightnode=&parsetree.back();
parsetree.pop_back();
temp->right=rightnode;
parsetree.push_back(temp); //can not put the temp into parsetree
}
else if(temp->val=="NOT")
{
TreeNode *leftnode = new TreeNode;
leftnode=&parsetree.back();
parsetree.pop_back();
temp->left=leftnode;
parsetree.push_back(temp);
}
else {
parsetree.push_back(temp);
}
}
I deal with string s from right to left
however when I run "TreeNode leftnode" when operator is "OR"; the lefenode was allocated an address which is using by first "AND"'s left child "pass", that is to say, the "AND"'s point to his left children at address 0x00007fff6d8da7e0, and the new temporary leftnode's is allocating address 0x00007fff6d8da7e0 too
after that
before that the tree is like
(AND)
/ \
/ \
pass (NOT)
/
reject
after that leftnode is allocated the address of "pass" it will like
(AND)
/ \
/ \
(AND) (NOT)
/ \ /
/ \ /
(AND) (NOT) reject
/ \
/ \
(AND) (NOT)
and etc, all point to itself, I know there maybe something wrong with pointer, but I can not figure out.
please help me
if(temp.val=="AND"||temp.val=="OR"||temp.val=="=>"||temp.val=="<=>"){
TreeNode leftnode; //appear a bug here
leftnode=parsetree.back();
parsetree.pop_back();
temp.left=&leftnode;
TreeNode rightnode;
rightnode=parsetree.back();
parsetree.pop_back();
temp.right=&rightnode;
parsetree.push_back(temp);
}
Your variables leftnode and rightnode have a limited lifespan. Since they are declared in the scope of your if, they will be destroyed once you step out of there. Meaning their adresses become invalid ! So, each time, the content of temp.left and temp.right is going to point to some garbage data.
This is actually why you can see that you find the same address multiple times : since the previous object has been destroyed, it is being used to store the new data that you need. But that's not exactly what you want, since you want to preserve all the objects that you've created.
The easiest way would be to dynamically create the TreeNodes you need (and modify the rest of your code accordingly):
TreeNode *leftnode = new TreeNode;
TreeNode *rightnode = new TreeNode;
That way, they will stay valid even after stepping out of the if.
You must however not forget to delete them afterwards.

Binary Tree search returns no results (C++)

I am working on some binary tree algorithms and need a "find node with searchindex..." function. The design for treenodes is basically
class TreeNode {
int index; // some identifier
TreeNode *left;
TreeNode *right;
}
and a tree is defined by a pointer to the root-node.
My implementation for the search function is:
void Tree::searchNode(TreeNode * root, int nodeIndex, TreeNode *resultNode){
/* Recursive search */
if (root->index == nodeIndex) {
resultNode = root;
} else {
/* search children if the current node is not a leaf */
if(!root->isLeaf()) {
this->searchNode(root->left,nodeIndex,resultNode);
this->searchNode(root->right,nodeIndex,resultNode);
}
}
}
Arguments: *root is the root-node of the tree, nodeIndex is the search-index and *resultNode is the pointer to the found (or not) node in the tree.
The function does not return a reference or pointer to the found node but modifies the pointer resultNode so it points to the found node. The idea is to initialize resultNode with NULL, perform the search and modify it if a match occurs. Otherwise it remains NULL and I can easily check if there are search results or not.
Another class with a tree buildingTree as member utilizes the search-function in this way:
TreeNode *resultNodePtr = NULL;
this->buildingTree->searchNode(this->buildingTree->rootPtr,
currentNodeIndex, resultNodePtr);
// do sth. with resultNodePtr if != NULL
I create *resultNodePtr on the stack because I just need it temporarily inside the function. Is this done correctly? However: The function does not work. resultNodePtr is always NULL, even if the tree contains a node with the search-index. I debugged it very carefully step by step, it detects
(root->index == nodeIndex)
correctly but
resultNode = root;
does not work (I want resultNode to point to the same adress root points to).
Debugger says resultNode before assignment is 0x0, root node is some adress, after the assignment resultNode remains 0x0.
Do I have to overload the operator= in this case for the class TreeNode?
I have tried it:
TreeNode & TreeNode::operator=(const TreeNode & oldTreeNode){
*this = oldTreeNode;
return *this;
// ignore childs for now
}
I am not an expert but this operator= seems trivial. Does it affect the assignment of two TreeNode pointers *node1 = *node2 at all?
Maybe you can help me. Thanks for reading, appreciate your help.
If I find a solution myself I will post it here.
Regards,
Mark
Because you pass resultNode into the function as a pointer by value, its original value never changes. Think of TreeNode* as literally nothing more than a number representing a memory address; when you reassign it:
resultNode = root;
This modifies the copy that searchNode has, but not the original pointer in the code which invokes searchNode. Take this simpler example:
void Foo(int x)
{
x = 100;
}
void Bar()
{
int x = 0;
Foo(x);
// at this point, x is still 0
}
resultNode's value doesn't change from NULL for the same reason that x doesn't change from 0 when the function Bar is invoked. To fix this issue, pass the pointer in as a pointer to a pointer, or a pointer by reference:
void Tree::searchNode(TreeNode* root, int nodeIndex, TreeNode*& resultNode)
{
// same code
}
... or:
void Tree::searchNode(TreeNode* root, int nodeIndex, TreeNode** resultNodePtr)
{
// assign to *resultNodePtr instead
}
Your resultNode pointer is being passed by value, not by reference. So when the function call completes the pointer on the calling side does not receive a value.
Your algorithm looks fine :)

How to structure this tree of nodes?

I'm writing a program in C++ that uses genetic techniques to optimize an expression tree.
I'm trying to write a class Tree which has as a data member Node root. The node constructor generates a random tree of nodes with +,-,*,/ as nodes and the integers as leaves.
I've been working on this awhile, and I'm not yet clear on the best structure. Because I need to access any node in the tree in order to mutate or crossbreed the tree, I need to keep a dicionary of the Nodes. An array would do, but it seems that vector is the recommended container.
vector<Node> dict;
So the Tree class would contain a vector dict with all the nodes of the tree (or pointers to same), the root node of the tree, and a variable to hold a fitness measure for the tree.
class Tree
{
public:
typedef vector<Node>dict;
dict v;
Node *root;
float fitness;
Tree(void);
~Tree();
};
class Node
{
public:
char *cargo;
Node *parent;
Node *left;
Node *right;
bool entry;
dict v;
Node(bool entry, int a_depth, dict v, Node *pparent = 0);
};
Tree::Tree()
{
Node root(true, tree_depth, v);
};
There seems to be no good place to put typedef vector<Node>dict;, because if it goes in the definition of Tree, it doesn't know about Node, and will give an error saying so. I havn't been able to find a place to typedef it.
But I'm not even sure if a vector is the best container. The Nodes just need to be indexed sequentally. The container would need to grow as there could be 200 to 500 Nodes.
I think a standard Binary Tree should do... here is an example of a (binary) expression tree node:
const int NUMBER = 0, // Values representing two kinds of nodes.
OPERATOR = 1;
struct ExpNode { // A node in an expression tree.
int kind; // Which type of node is this?
// (Value is NUMBER or OPERATOR.)
double number; // The value in a node of type NUMBER.
char op; // The operator in a node of type OPERATOR.
ExpNode *left; // Pointers to subtrees,
ExpNode *right; // in a node of type OPERATOR.
ExpNode( double val ) {
// Constructor for making a node of type NUMBER.
kind = NUMBER;
number = val;
}
ExpNode( char op, ExpNode *left, ExpNode *right ) {
// Constructor for making a node of type OPERATOR.
kind = OPERATOR;
this->op = op;
this->left = left;
this->right = right;
}
}; // end ExpNode
So when you're doing crossover or mutation and you want to select a random node you just do the following:
Count the number of nodes in the tree (only need to do this ones in the constructor).
Select a random index from 0 to the size of the tree.
Visit each node and subtract 1 from the random index until you reach zero.
Return the node when the index is 0.
In this case you don't need to know anything about the parent of the node. So mating/mutation should look like this:
select nodeX
select nodeY
if( Rand(0,1) == 1 )
nodeY->left = nodeX;
else
nodeY->right = nodeX;
And that should be it...
I don't think the Node or the Tree are the first classes to write.
I'd start with Expression. In your case you need at least a BinaryExpression, as well as an expression with no subnodes (constants or variables). Each Binary expression should contain auto_ptr<Expression> lhs and auto_ptr<Expression> rhs.
You could then easily write a function to enumerate through the expression tree's members. If performance turns out to be relevant, you can cache the list of expressions in the tree, and invalidate it manually when you change the expression. Anything more advanced is likely to be slower and more error prone.
I don't see why an expression needs to know it's parent expression. It only makes life harder when you start editing expressions.
You may implement a list over nodes. Then, each node will have two additional pointers inside:
class Node{
...
Node* sequentialPrevious;
Node* sequentialNext;
...
}
And so will the tree:
class Tree{
...
Node* sequentialFirst;
Node* sequentialLast;
...
}
Than you will be albe to move bidirectionally over nodes just by jumping to sequentialFirst or sequentialLast and then iteratively to sequentialNext or sequentialPrevious. Of course, Node constructor and destructor must be properly implemented to keep those pointers up to date.