I have tow code about the the question Binary Tree Pruning.
this is a wrong code
class Solution {
public:
TreeNode* pruneTree(TreeNode* root) {
if(root == NULL)
return NULL;
if((root->left = pruneTree(root->left)) == NULL &&
(root->right = pruneTree(root->right)) == NULL){
if(root->val == 0){
delete root;
return NULL;
}
}
return root;
}
};
this is my passed code
class Solution {
public:
TreeNode* pruneTree(TreeNode* root) {
if(root == NULL)
return NULL;
root->left = pruneTree(root->left);
root->right = pruneTree(root->right);
if(root->left == NULL && root->right == NULL){
if(root->val == 0){
delete root;
return NULL;
}
}
return root;
}
};
I want to know what cause the difference between the two programs
In the second code, it is guaranteed that both pruneTree(root->left) and pruneTree(root->right) are called, because those are two separate expressions.
root->left = pruneTree(root->left);
root->right = pruneTree(root->right);
In the first code you have:
(root->left = pruneTree(root->left)) == NULL &&
(root->right = pruneTree(root->right)) == NULL
The difference here is that pruneTree(root->left) and pruneTree(root->right) are in one expression, so they might (and this case the do) depend on each other.
If (root->left = pruneTree(root->left)) == NULL evaluates to false then the parte after the && does not need to be evaluated, because the complete expression can't become true anymore.
Related
Hello I currently both the working and not working solutions below for the problem
Given the root of a BINARY TREE:
Collect all the leaf nodes.
Remove all the leaf nodes.
Repeat until the tree is empty.
HOWEVER it only works when I go set the current->left || current->right to null if they are leaves
In my second example if I try to set current = NULL when it's a leaf node it doesn't update. Please help I will respond to any questions this is based on LEETCODE336
//NEED HELP ON THIS ONE NOT WORKING
class Solution {
public:
vector<vector<int>> findLeaves(TreeNode* root) {
vector<vector<int>> result;
if(root == NULL) return result;
queue<TreeNode*> bfs;
vector<int> leaves;
while(root){
bfs.push(root);
while(!bfs.empty()){
TreeNode* current = bfs.front();
bfs.pop();
if(current->left != nullptr) bfs.push(current->left);
if(current->right != nullptr) bfs.push(current->right);
if(current->left == nullptr && current->right == nullptr){
leaves.push_back(current->val);
// NOT SETTING TO NULL WHEN IT'S A LEAF NODE
current = NULL;
}
}
result.push_back(leaves);
leaves.clear();
}
return result;
}
};
class Solution {
public:
bool isLeaf(TreeNode* current){
if(current->left == NULL && current->right == NULL) return true;
else
return false;
}
vector<vector<int>> findLeaves(TreeNode* root) {
vector<vector<int>> result;
if(root == NULL) return result;
queue<TreeNode*> bfs;
vector<int> leaves;
// bfs.push(root);
while(root != NULL){
if(isLeaf(root)){
leaves.push_back(root->val);
root = nullptr;
}
else {
bfs.push(root);
}
while(!bfs.empty()){
TreeNode* current = bfs.front();
bfs.pop();
if(current->left && isLeaf(current->left)){
leaves.push_back(current->left->val);
current->left = nullptr;
}
else if(current->left){
bfs.push(current->left);
}
if(current->right && isLeaf(current->right)){
leaves.push_back(current->right->val);
current->right = nullptr;
}
else if(current->right){
bfs.push(current->right);
}
}
result.push_back(leaves);
leaves.clear();
}
return result;
}
};
I was solving this question https://leetcode.com/problems/binary-tree-pruning/description/ and came up with the solution directly below (which doesn't change the tree at all). When i debug this, it does enter the if statement - meaning it recognizes that a and b are both null for the leaf node, but when I assign root=nullptr it doesn't actually change the root (which is a leaf) to null. why doesn't my code work as it should?
TreeNode* pruneTree(TreeNode* root) {
if (root == nullptr){return nullptr;}
TreeNode *a = pruneTree(root->left);
TreeNode *b = pruneTree(root->right);
if (root->val == 0 && a==nullptr && b== nullptr){
return nullptr; // or root = nullptr, they have same effect
}
return root;
}
I am just confused on why it actually does change the value of the pointer to null when using the code below, when the only thing that is different is
root->left = pruneTree(root->left);
root->right = pruneTree(root->right);
the correct answer is:
TreeNode* pruneTree(TreeNode* root) {
if (root == nullptr){return nullptr;}
root->left = pruneTree(root->left);
root->right = pruneTree(root->right);
if (root->val == 0 && root->left == nullptr && root->right == nullptr){
return nullptr;
}
return root;
}
my guess would be that this gives us direct access to not only the spot in memory for the left and right children, but also for the root itself? (which is why we are able to "delete" it?) not really delete but just return nullptr for it.
so am having problems with the exception during deletion(Exception thrown: read access violation.
parent was 0x158398.)like that sometimes are different numbers etc and always its about parent object/pointer, my code is working without any errors,exceptions till 100k objects then sometimes works sometimes not, for 1 milion is not even working anymore.If anybody could help out would be great. under post am posting code:
Node Class:
template <class T>
class Node {
public:
T data;
Node<T>* Left = NULL;
Node<T>* Right = NULL;
};
the code for finding min of right subtree:
Node<T>* findMin(Node<T>* node)
{
while (node->Left != NULL)
node = node->Left;
return node;
}
code for Deletion:
void Delete(Node<T>*& node) {
if (node == NULL)
return;
Node<T>* parent = findParentForDelete(this->root, node);
Node<T>* temp = NULL;
//leafs
if (node->Left == NULL && node->Right == NULL) {
if (node == root) {
delete root;
root = NULL;
return;
}
else {
if (parent->Left == node) //line with exception
parent->Left = NULL;
else
parent->Right = NULL;
delete node;
node = NULL;
return;
}
}
//1 child left not null
else if (node->Left != NULL && node->Right == NULL)
{
if (node == root) {
temp = root->Left;
delete root;
root = NULL;
root = temp;
return;
}
else {
if (parent->Left == node)
parent->Left = node->Left;
else
parent->Right = node->Left;
delete node;
node = NULL;
return;
}
}
//1 child Right not null
else if (node->Left == NULL && node->Right != NULL)
{
if (node == root) {
temp = root->Right;
delete root;
root = NULL;
root = temp;
return;
}
else {
if (parent->Left == node)
parent->Left = node->Right;
else
parent->Right = node->Right;
delete node;
node = NULL;
return;
}
}
//2 childs
else if (node->Left != NULL && node->Right != NULL)
{
temp = findMin(node->Right);
T data = temp->data;
Delete(temp);
node->data = data;
}
}
finding parent:
Node<T>* findParentForDelete(Node<T>* node, Node<T>*& nodeToFind)
{
if (node == NULL)
return NULL;
if (node->Left == NULL && node->Right == NULL)
return NULL;
if ((node->Left != NULL && node->Left == nodeToFind)
|| (node->Right != NULL && node->Right == nodeToFind))
return node;
if (node->data->age > nodeToFind->data->age)
return findParentForDelete(node->Left, nodeToFind);
if (node->data->age < nodeToFind->data->age)
return findParentForDelete(node->Right, nodeToFind);
}
findParentForDelete does not always return a value.
It will not return a value if the node you're looking for has an age that is the same as a different node in the tree, so the value returned to the caller will be a garbage value.
If you increase the warning level when you compile, most compilers will issue a warning for this.
I'm implementing a custom BST which stores data in leaves and each node represents its subtree's smallest value. The left nodes store the higher values and the right nodes store the lower values.
I then delete the data by deleting the leaves and updating the internal nodes, but somehow my deletion could not work.
Here is my code, hope you can point out something wrong with it. Thank you very much.
inline BstNode* BstDelete(BstNode* root, rectangle del){
if (root == NULL) return root;
else if (del > root->data){
root->left = BstDelete(root->left,del);
if(root->left == NULL) root->data = root->right->data;
root->data = root->left->data;
}
else if(del < root->data){
root->right = BstDelete(root->right,del);
if (root->right == NULL) root->data = root->left->data;
root->data = root->right->data;
}
else {
//found
//Case1: No Child
if (root -> left == NULL && root->right == NULL){
delete root;
root = NULL;
}
//One child
else if (root->left == NULL){
root->right = BstDelete(root->right, del);
if(root->right ==NULL) root = root->right;
else root->data = root->right->data;
}
else if (root->right == NULL){
root->left = BstDelete(root->left,del);
if(root->left == NULL) root = root->left;
else root->data = root->left->data;
}
// 2 children
else {
root->right = BstDelete(root->right, del);
if (root->right == NULL) root->data = root->left->data;
else root->data = root->right->data;
}
}
return root;}
Whenever I insert the tree data in, and try to delete them, it works for all except the last remaining node. Or even if I insert only one node and try to delete it, it doesn't, it continues displaying the node. I tried debugging the code, but seems clueless. Please help!
void Remove(node *Current, int key) {
node *prev = new node;
if(Current == NULL)
cout << "List is empty.\n";
else {
while(Current != NULL) {
if(Current->value == key)
break;
else {
prev = Current;
if(Current->value >key)
Current = Current->left;
else
Current = Current->right;
}
}
if(Current->left == NULL && Current->right == NULL) {
if(prev->left == Current)
prev->left = NULL;
else
prev->right = NULL;
delete(Current);
}
else if(Current->left != NULL && Current->right == NULL) {
if(prev->left == Current)
prev->left = Current->left;
else
prev->right = Current->left;
delete(Current);
}
else if(Current->left == NULL && Current->right != NULL) {
if(prev->left == Current)
prev->left = Current->right;
else
prev->right = Current->right;
delete(Current);
}
else if(Current->left != NULL && Current->right != NULL) {
node *temp = Current->right;
if(temp->left == NULL && temp->right == NULL) {
Current->value = temp->value;
delete(temp);
Current->right = NULL;
}
//////////////////////////////////////
else if(Current->right->left != NULL)
{
node *left_current = Current->right;
node *left_current_prev = Current->right->left;
while(left_current->left != NULL)
{
left_current_prev = left_current;
left_current = left_current->left;
}
Current->value = left_current->value;
delete(left_current);
left_current_prev->left = NULL;
}
//////////////////////////////////////
else
{
node *temp;
temp = Current->right;
Current->value = temp->value;
Current->right = temp->right;
delete(temp);
}
//////////////////////////////////////
}
}
}
if I insert only one node and try to delete it, it doesn't, it
continues displaying the node
Every tree has a base, a pointer to the first node of the tree.
tree base --> Current node --> left node ...
--> right node ,,,
This base pointer appears to be available to the caller of function Remove,
... code leading to
Remove (tree base->Current, key)
... subsequent code
but you did not give Remove access to the tree base to modify it.
In other words, Remove() (probably) deletes Current, but tree base still points to where Current was when Remove() returns.
You probably need to review what happens when the key does not match the value in the last node.