Working in C++ here. I am trying to develop a specific program that creates a BST from its preorder traversal. Here's the first batch of code:
class Node {
private:
int val;
Node *left;
Node *right;
public:
Node () : val(0), left(NULL), right(NULL) {}
Node (int v) : val(v), left(NULL), right(NULL) {}
Node (int v, Node *l, Node *r) : val(v), left(l), right(r) {}
Node& operator = (Node& rhs) {
if (&rhs == this) return *this;
val = rhs.val;
left = rhs.left;
right = rhs.right;
return *this;
}
}*root;
I've taken out some of the functions but that's the basics. Now here's the other piece of code:
Node *temp = new Node();
if (preorder[trav] <= N)
{
temp = root;
root->goLeft(pre_ordered, traverse);
traverse++;
}
else
{
temp = root;
root->goRight(pre_order, traverse);
traverse++;
}
However, I then get " error: invalid conversion from 'Node*' to 'int' " on the line "temp = root". Any ideas? It seems to me I'm setting one node equal to the other so I don't understand what's wrong. Looked online and found nothing helpful. Some similar errors, but just different enough to not be useful.
I'll be upfront that this is for a school assignment so I'm not looking for direct answers. Just hints about what I need to change or where I need to look would be great! Thanks.
EDIT: Exact error is:
main.cpp:160:15: error: invalid conversion from ‘Node*’ to ‘int’ [-fpermissive]
temp = root;
^
EDIT I found it. I apologize.
I was stupid and didn't look hard enough to find that I was redefining "temp" as an int in the main function. Sorry for wasting your time guys.
Can't answer my own question since not enough rep.
The names of the members you have declared do not match what you used in the code. For example, you declared int value but reference it by the name val
Corrected code that compiles is:
class Node {
private:
int val;
Node *left;
Node *right;
public:
Node () : val(0), left(NULL), right(NULL) {}
Node (int v) : val(v), left(NULL), right(NULL) {}
Node (int v, Node *l, Node *r) : val(v), left(l), right(r) {}
Node& operator = (Node& rhs) {
if (&rhs == this) return *this;
val = rhs.val;
left = rhs.left;
right = rhs.right;
return *this;
}
}*root;
int main()
{
Node *temp = new Node();
temp = root;
return 0;
}
I know you didn't want a direct answer, but it seemed like an actual mistake, and not a lack of understanding.
Related
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
TreeNode*& node = find(root, val);
node = new TreeNode(val);
return root;
}
TreeNode*& find(TreeNode*& root, int& val) {
if (root == nullptr) return root;
else if (root->val > val) return find(root->left, val);
else return find(root->right, val);
}
};
I am learning C++ and read this code on a lecture slide. The code is about the insertion of a new node into a binary search tree. The idea is to find the target location and then insert a new node to the location. I can understand the reason for the 'find' function returning a 'reference to pointer' type. I think it is because we need to modify the address of the target location after the 'find' function returns. However, I don't know why we need to use the 'reference to pointer' type also when we pass the root node into the 'find' function. If I change TreeNode*& find(TreeNode*& root, int& val) to TreeNode*& find(TreeNode* root, int& val), the program will return the original tree without the target insertion. Can anyone help with this question? Thank you in advance!
If you change find to TreeNode*& find(TreeNode* root, int& val) then look at the first line of the function:
if (root == nullptr) return root;
This would return a reference to a local variable. Changing it in insertIntoBST is undefined behavior and will not change the root variable inside insertIntoBST.
Go through the code step by step when inserting the first value into an empty tree:
NodeTree *tree = nullptr;
tree = insertIntoBST(tree, 42);
The insertIntoBST function could use the same trick as find and modify the root in place:
void insertIntoBST(TreeNode*& root, int val) {
TreeNode*& node = find(root, val);
node = new TreeNode(val);
}
NodeTree *tree = nullptr;
insertIntoBST(tree, 42);
insertIntoBST(tree, 23);
insertIntoBST(tree, 666);
or even shorter:
void insertIntoBST(TreeNode*& root, int val) {
find(root, val) = new TreeNode(val);
}
I was doing a Leetcode challenge and my code used about .5 kb of memory more than other submissions that looked more complex. The challenge itself was inverting a binary tree. Although I submitted my solution multiple times to take the average values of runtime and memory usage for my code.
My code below runs on average for 3ms and takes 8.5 kb of memory after 10 trial submissions.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if(root == nullptr) return root;
invertTree(root -> left);
invertTree(root -> right);
TreeNode* tmp = root ->left;
root -> left = root -> right;
root -> right = tmp;
return root;
}
};
The code below is the sample submission that Leetcode shows as an example of 0ms runtime and 8kb of memory usage
class Solution {
public:
void invert(TreeNode* root)
{
if(root==nullptr)
return;
invert(root->left);
invert(root->right);
TreeNode* temp = root->right;
root->right = root->left;
root->left = temp;
}
TreeNode* invertTree(TreeNode* root) {
if(root==nullptr)
return nullptr;
invert(root);
return root;
}
};
I am wondering how the code given uses two functions and uses less memory than my solution? Additionally, I am relatively new to programming, and am wondering if this case is exemplary of deeper mechanic within the C++ language or too nitpick-y to warrant any concern. Thanks for reading
i tried to create BST on cpp
i done the class Node in the class Tree because it's logical.
header:
class Node;
class Tree
{
public:
Node* root;
Tree();
Tree(int val);
void insert(int val);
class Node
{
public:
Node();
Node(int val);
Node* right;
Node* left;
int val;
};
};
implamation:
Tree::Tree()
{
this->root = NULL;
}
Tree::Node::Node()
{
}
Tree::Node::Node(int val)
{
this->val = val;
this->left = NULL;
this->right = NULL;
}
void Tree::insert(int val)
{
this->root = new Node(3);
}
i got an error on
this->root = new Node(3);
IntelliSense: a value of type "Tree::Node *" cannot be assigned to an entity of type "Node *"
error C2440 : '=' : cannot convert from 'Tree::Node *' to 'Node *'
what did i done wrong please?
root this Node*
and new Node (3) return Node*
what is the problem?
thanks!!!
To my understanding, in your current implementation, you are declaring two classes with the name Node; one is in the global scope while the other one is in the scope of the class Tree. This can be solved by using only one class.
I am trying to make a linked list for my C++ class and I was looking at some code from my professor:
void List::add(char c)
{
Node *newNode(new Node(c));
if (last == nullptr)
first = last = newNode;
else {
last->next = newNode;
last = newNode;
}
}
int List::find(char c)
{
Node *node(first);
int i(0);
while (node) {
if (node->c == c)
return i;
node = node->next;
i++;
}
return -1;
The following is the class declaration from the header file:
class List
{
public:
List(void);
~List(void);
void add(char c);
int find(char c);
bool remove(int index);
int length(void);
friend std::ostream& operator<<(std::ostream& out, List& list);
private:
class Node
{
public:
Node(char c) : c(c), next(nullptr) { }
char c;
Node *next;
};
Node *first;
Node *last;
};
First question: what do the parentheses mean and what is the correct way to use them?
Node *newNode(new Node(c));
Node *node(first);
int i(0);
Second question: What does the following mean?
Node(char c) : c(c), next(nullptr) { }
I have defined a node in the past using a struct; is the syntax different because this is a class?
This statements
Node *newNode(new Node(c));
Node *node(first);
int i(0);
are equivalent to
Node *newNode = new Node(c);
Node *node = first;
int i = 0;
This constructor of the class Node
Node(char c) : c(c), next(nullptr) { }
uses mem-initializer list : c(c), next(nullptr) to initialize data members of the class.
That is data member c is initialized by constructor parameter c and data member next is initialized by pointer literal nullptr
I have written a simple LinkedList class. I first have a Node class:
class Node
{
public:
Node* next;
int value;
Node(int val)
{
value = val;
next = NULL;
}
Node(int val, Node* y)
{
value = val;
next = y;
}
}
then implementation for LinkedList is straightforward, with a Node* head member and a addNode(int value) member function.
What are other methods to implement a linked list? could give other such implementations or hint at relevant doc?
Thanks and regards.
The standard library defines a doubly-linked list implementation you can use (see here, for example). I'd advise using that unless you have a very good reason not to.
Boost has some implementations:
http://www.boost.org/doc/libs/1_51_0/doc/html/intrusive/slist.html
http://www.boost.org/doc/libs/1_51_0/doc/html/intrusive/list.html
deleteNode
findNode
Mabe create an iterator.
Also better to use initialisation lists in the constructors and private data members. NULL is for C, use 0 instead.
i.e.
class Node
{
private:
Node* next;
int value;
public:
Node(int val) : next(0), value(val) {}
Node(int val, Node *n) : next(n), value(val) {}
int getVale() { return value}
};