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.
Related
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]);
}
}
I have a data structures project I have to do for my Uni class which is to implement a stack with a linked list; simple stuff. We have had some help, code-wise, to show us the correct way to implement such a structure.
Stack class:
class Stack
{
public:
Stack(void)
{
top = NULL; // Initialises defualt top node pointer.
}
~Stack(void)
{
while (NodePop() != NULL){}
}
void Push(int value) // Pushes a new node onto the stack.
{
Node* temp = new Node(value, top); // Creates a temporary node with a value and makes it
// point to the top node as the next node in the stack.
top = temp; // Temporary node becomes the top node in the stack.
}
Node* NodePop(void)
{
/* Remove top node from the stack */
Node* temp = top; // Creates a temporary node to return, sets it to top node.
if (top != NULL) top = top->getNext(); // Points the stacks top node to the next node in the list.
return temp; // Returns a pointer to the popped node still in the heap.
}
int Pop(void) // Pops the top node off of the stack. Returns the nodes value.
{
Node* temp = NodePop();
int valueReturn = 0;
/* Sets the return value */
if (temp != NULL)
{
valueReturn = temp->getVal(); // Set return value to the nodes value if there is a node left.
}
else
{
throw "Stack Empty"; // Throws exception if temp is NULL and stack is empty.
}
delete temp; // Deletes the node entirely from the heap.
return valueReturn;
}
private:
Node* top;
};
Node class:
class Node
{
public:
Node(int value, Node* nextptr = NULL, Node* prevptr = NULL, int currentpriority = 0)
{
/* Set initial variables for the node at creation */
this->value = value;
this->next = nextptr;
this->prev = prevptr;
this->priority = currentpriority;
}
// bunch of getters and setters...
private:
Node* next; // Pointer to the next node.
Node* prev; // Pointer to the previous node.
int priority; // Stores the node priority as a number 0-9.
int value; // Stores the node value for printing.
};
We cannot change any of the classes structure (too my annoyance, NodePop() should be private, but w/e).
So here NodePop() essentially removes the top node from the list but doesn't delete it; it removes all reference to it from the linked list but it never deletes it from the heap, it's only deleted from the heap in Pop(). All good (except for being able to call NodePop() publicly, but again, I'm not allowed to make it private). But when I call the destructor is has to use NodePop(), not Pop().
So does that mean the node is never deleted from the heap when NodePop() runs from the destructor?
If so how would I delete them because it's going to run nodePop() if i have it in a while, do-while, or if statement condition so there will always be one node left undeleted?
Looking at the code in question
~Stack(void)
{
while (NodePop() != NULL){}
}
Node* NodePop(void)
{
/* Remove top node from the stack */
Node* temp = top; // Creates a temporary node to return, sets it to top node.
if (top != NULL) top = top->getNext(); // Points the stacks top node to the next node in the list.
return temp; // Returns a pointer to the popped node still in the heap.
}
Your destructor calls NodePop() until that function returns NULL. Let's look at what NodePop() does. The comment in the code claims that it Creates a temporary node to return That is not true. It creates a pointer to a Node (a Node*) and sets that pointer to point the same place that top does. If top is not null, it sets top to point to top's next node. It the returns temp, which is a pointer to what was originally the top Node.
At no point to you release memory associated with any Node, so yes there is a memory leak.
You can fix the leak by deleting each Node* that you encounter in the destructor that is not NULL.
Indeed, the nodes are not deleted, and this code will leak. You can verify that by using a tool like Valgrind.
I would change the while to something like while (Node *N = NodePop()) delete N;
FYI, this code is definitely not idiomatic C++11. It's basically poorly written C, and I'd expect to find more bugs in it. Your teacher should get a slap on the wrist for presenting C++11 like this :-)
I have a tree structure that i am creating the following way. The tree is created correctly as far as i know. But when i want to get the data from a node, i get some weird acsii symbols.
How I set the data.Lets say its empty. Doesn't matter at the moment. I have a value in my program. The function feeds itself until i get to the end of the data.
struct Node {
char Data;
Node* Left;
Node* Right;
};
Node maketree(0,s,split)
{
Node node;
node.Data=' ';
Node n1=subsplit(0,s,splitingat);
Node n2= subsplit(1,splitingat+1,e);
node.Left=&n1;
node.Right=&n2;
return node;
}
This is how i get data from the tree.
char decode(Node node,string text)
{
int currentindex=0;
Node sub=node;
{
}
if(text[currentindex]=='0')
{
sub=*sub.Left;
cout<<" x "<<sub.Data<<endl;
}
else if(text[currentindex]=='1')
{
sub=*sub.Right;
cout<<" x "<<sub.Data<<endl;
}
// cout<<sub.Data<<endl;
}
I think that the mistake is that I am printing out the pointer and not the node. But I don't know where I went wrong.
The source of your problem appears to be here:
Node node;
node.Data=' ';
Node n1=subsplit(0,s,splitingat);
Node n2= subsplit(1,splitingat+1,e);
node.Left=&n1; // danger Will Robinson!
node.Right=&n2;
return node;
You're taking the addresses of local, temporary, automatic variables and storing them in pointers that you return through node. As soon as that return executes, n1 and n2 are destroyed and node.Left and node.Right are left pointing to garbage. You may be able to fix this like so:
Node* n1=new Node(subsplit(0,s,splitingat));
Node* n2=new Node(subsplit(1,splitingat+1,e));
// side note: probably better to have subsplit() return dynamically-allocated Node*s to avoid the copy
node.Left=n1;
node.Right=n2;
but you may still have issues crop up if similar things are being done elsewhere.
Kind of along the same lines, in your second block of code, you are making a copy of each node you examine and storing it into sub. It would probably make more sense to have sub be a Node*.
And finally, to avoid memory management issues (almost) altogether, use shared_ptr<Node> instead of Node* in all of the above. :)
edit
Clafification: The intention is not to remove the node from the original list. But to create an identical node (data and children wise) to the original and insert that into the new list. In other words, a "move" does not imply a "remove" from the original.
endedit
The requirements:
Each Node in the list must contain a reference to its previous sibling
Each Node in the list must contain a reference to its next sibling
Each Node may have a list of child nodes
Each child Node must have a reference to its parent node
Basically what we have is a tree structure of arbitrary depth and length. Something like:
-root(NULL)
--Node1
----ChildNode1
------ChildOfChild
--------AnotherChild
----ChildNode2
--Node2
----ChildNode1
------ChildOfChild
----ChildNode2
------ChildOfChild
--Node3
----ChildNode1
----ChildNode2
Given any individual node, you need to be able to either traverse its siblings. the children, or up the tree to the root node.
A Node ends up looking something like this:
class Node
{
Node* previoius;
Node* next;
Node* child;
Node* parent;
}
I have a container class that stores these and provides STL iterators. It performs your typical linked list accessors. So insertAfter looks like:
void insertAfter(Node* after, Node* newNode)
{
Node* next = after->next;
after->next = newNode;
newNode->previous = after;
next->previous = newNode;
newNode->next = next;
newNode->parent = after->parent;
}
That's the setup, now for the question. How would one move a node (and its children etc) to another list without leaving the previous list dangling?
For example, if Node* myNode exists in ListOne and I want to append it to listTwo.
Using pointers, listOne is left with a hole in its list since the next and previous pointers are changed. One solution is pass by value of the appended Node. So our insertAfter method would become:
void insertAfter(Node* after, Node newNode);
This seems like an awkward syntax. Another option is doing the copying internally, so you'd have:
void insertAfter(Node* after, const Node* newNode)
{
Node *new_node = new Node(*newNode);
Node* next = after->next;
after->next = new_node;
new_node->previous = after;
next->previous = new_node;
new_node->next = next;
new_node->parent = after->parent;
}
Finally, you might create a moveNode method for moving and prevent raw insertion or appending of a node that already has been assigned siblings and parents.
// default pointer value is 0 in constructor and a operator bool(..)
// is defined for the Node
bool isInList(const Node* node) const
{
return (node->previous || node->next || node->parent);
}
// then in insertAfter and friends
if(isInList(newNode)
// throw some error and bail
I thought I'd toss this out there and see what folks came up with.
Let's call the node that we are going to remove current. Only the nodes pointed to by current, namely current->previous, current->next, current->child, and current->parent refer to the node current. For example, current->previous->next == current if the current node's previous node is non-null. So, we can easily excise the current node from the list like so:
Vertical Links
A node keeps its children, but it needs to be excised from its parent. This is done like so:
Let parent = current->parent
if parent is non-null:
if parent->child == current:
parent->child = current->next
current->parent = null
Horizontal Links
The following code unlinks the current node in the horizontal (next/previous) direction:
Let prev = current->previous
Let next = current->next
if prev is non-null:
prev->next = next
if next is non-null:
next->previous = prev
current->previous = null
current->next = null
Granted, this is still a bit messy, but if you break the linked list functionality into small functions (which it looks like you are already doing) and use good comments, then it's really not that bad, I don't think.
First, I agree that, if you're copying the node and not actually removing it from the original tree, the operation should be called a copy, not a move!
Second, I recommend you separate the operation that actually does the copying from the operation that does insertion. This will make it much more flexible, if say for example you need to insert nodes from other sources into your destination, or you want to copy the node for other purposes.
Third, you didn't specify whether Node is polymorphic. If it is, I would implement a method like the following to do the copy:
virtual Node* clone();
You have a couple of design decisions to make here:
Do you want to preserve next, prev, and parent when you do a clone? I think it makes sense to zero them out.
Do you want to do a deep copy of the children as well when you do a clone? Depending on the use case, you may want to do one or the other, or allow for both.
Fourth, you assume that insertion should fail if the parent/prev/next pointers are already set. You can do this, but you may benefit down the road from a more powerful insertion operation that simply removes nodes from their existing tree in this case. Either will behave consistently.
Fifth, you can't be passing const Nodes around if you're going to be fixing up that node's pointers.
Let's assume for the moment that you decide to zero out the linked list pointers but decide to deep copy the children. Then your code might look like:
class Node {
public:
Node() : prev(NULL), next(NULL), parent(NULL), child(NULL) { }
virtual Node* clone() {
Node* newN = new Node();
newN->cloneChildren(*this);
return newN;
}
Node* lastChild() const { /* left as exercise */ }
void insert(Node* node_) { insertAfter(node_, lastChild()); }
void insertAfter(Node* node_, Node* prevSibling_) {
ASSERT(node_);
if (! prevSibling_) { // assume we want to push to front of child list
prevSibling_ = child; // will be NULL if we have no children
}
ASSERT(! prevSibling_ || prevSibling_->parent == this);
if (node_->parent) {
// assume you want to move the child in this case
node_->parent->remove(node_);
}
node_->parent = this;
node_->prev = prevSibling_;
if (prevSibling_) {
node_->next = prevSibling_->next;
prevSibling_->next = node_;
} else {
/* the new child is the only child - left as exercise */
}
}
void remove(Node* child_) { /* left as exercise */ }
protected:
virtual void cloneChildren(const Node& rhs) { /* left as exercise */ }
};
And the code that does the copying from one tree to another simply looks something like:
Node* myNode = ...
Node* someChildInListTwo = findPlaceToInsert(listTwo);
listTwo->insertAfter(myNode->clone(), someChildInListTwo);
In this case we have turned your one somewhat tangled operation into a set of discrete operations that you can use in a wide variety of cases:
a clone() operation that allows you to copy arbitrary nodes, whether or not they've been added to trees yet
an insert() operation that will automatically do a move for you if you want, and correctly handles adding to the front of the child list
a remove() operation that fell out naturally as a byproduct of how we wanted insertion to behave, but which can be used on its own
a simple mechanism to copy+insert the node if you don't want to remove the node from the original tree
I have a BST which is a linked list in C++. How would I delete the whole thing from memory? Would it be done from a class function?
Just delete the children:
struct TreeNode {
TreeNode *l, *r, *parent;
Data d;
TreeNode( TreeNode *p ) { l = nullptr; r = nullptr; parent = p; }
TreeNode( TreeNode const & ) = delete;
~TreeNode() {
delete l; // delete does nothing if ptr is 0
delete r; // or recurses if there's an object
}
};
or if you're using unique_ptr or some such, that's not even needed:
struct TreeNode {
unique_ptr< TreeNode > l, r;
TreeNode *parent;
Data d;
TreeNode( TreeNode *p ) { l = nullptr; r = nullptr; parent = p; }
TreeNode( TreeNode const & ) = delete;
~TreeNode() = default;
};
If you have access to the linked list itself, it's a piece of cake:
// Making liberal assumptions about the kind of naming / coding conventions that might have been used...
ListNode *currentNode = rootNode;
while(currentNode != NULL)
{
ListNode *nextNode = currentNode->Next;
delete currentNode;
currentNode = nextNode;
}
rootNode = NULL;
If this is a custom implemention of a BST, then this may well be how it works internally, if it has tied itself to a particular data structure.
If you don't have access to the internals, then Potatoswatter's answer should be spot on. Assuming the BST is setup as they suggest, then simply deleting the root node should automatically delete all the allocated memory as each parent down the tree will delete its children.
If you are asking how to go about iterating across a binary tree manually, then you would do the following recursive step:
void DeleteChildren(BSTNode *node)
{
// Recurse left down the tree...
if(node->HasLeftChild()) DeleteChildren(node->GetLeftChild());
// Recurse right down the tree...
if(node->HasRightChild()) DeleteChildren(node->GetRightChild());
// Clean up the data at this node.
node->ClearData(); // assume deletes internal data
// Free memory used by the node itself.
delete node;
}
// Call this from external code.
DeleteChildren(rootNode);
I hope I've not missed the point here and that something of this helps.
Perform a post-order traversal of the tree (i.e. visiting children before parents), and delete each node as you visit it.
Whether or not this has anything to do with classes depends entirely on your implementation.
With the limited information provided ....
If you allocated the nodes with new or malloc (or related functions) than you need to traverse over all the nodes and free or delete them.
An alternative is to put shared_ptr's (and weak_ptr's to kill cyclics) in your allocations -- provided you do it correctly you won't have to free the nodes manually
If you used a quality implementation that you picked up on the internet than provided the classes don't leak, you don't have to worry about anything.
Use smart pointers and forget about it.