Why doesn't this swap the two nodes? - c++

I am trying to solve a question from leetcode - deleting a node from a BST. We would be given the root node of a BST and a key; and we have to deleted the node with that key as the value. We can assume that all the tree nodes have unique values. We have to return the root node post this operation. (question link is: https://leetcode.com/problems/delete-node-in-a-bst/description/).
I wrote the following code:
// Example program
#include <iostream>
#include <string>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode* findSmallest(TreeNode* root) {
if(!root) return NULL;
TreeNode* prev=root;
while(root->left) {
cout<<"Visiting: "<<root->val<<"\n";
prev=root;
root=root->left;
}
prev->left=NULL;
cout<<"Returning: "<<root->val<<" and prev was: "<<prev->val<<"\n";
return root;
}
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return NULL;
if(root->val == key) {
//This is the node to be deleted
TreeNode* smallestOnRight = findSmallest(root->right);
//the lines below do not actually change the root node - why?
if(smallestOnRight) smallestOnRight->left=root->left;
if(smallestOnRight) smallestOnRight->right=root->right;
root=smallestOnRight;
return root;
}
if(root->val>key)
deleteNode(root->left, key);
if(root->val<key)
deleteNode(root->right, key);
return root;
}
int main()
{
TreeNode* root = new TreeNode(8);
root->left = new TreeNode(3);
root->left->left = new TreeNode(1);
root->left->right = new TreeNode(6);
root->left->right->left = new TreeNode(4);
root->left->right->right = new TreeNode(7);
root->right = new TreeNode(10);
root->right->right = new TreeNode(14);
root->right->right->left = new TreeNode(13);
deleteNode(root, 3);
}
I am wondering why the lines below the comment do not actually change the root node. So, if the original tree was like (a), then after this process, the new tree is like (b), whereas it should have been like (c):
(a): Image (a)
(b): Image (b)
(c): Image (c)
So, basically only the node3 should be replaced with node4, but unfortunately this does not happen. Why is this so?
Edit: So the input would be:
[8,3,10,1,6,null,14,null,null,4,7,13,null]
3
(Tree is traversed in level order).
Edit: Here is the cpp.sh link: http://cpp.sh/9h2z

You have not preserved node8 that should have been modified to point to node4. You need to preserve the parent of the node that is being deleted and modify the linkage in there.

Related

Function for inserting a value in binary tree?

I have a function insert that is used to insert values into the Binary tree.
But when I log out the value nothing is shown.
I'm aware of the insertion using member function.
The root node's value is not being updated?
Could someone tell me where I'm going wrong?
#include <iostream>
using namespace std;
class Node{
public:
int value;
Node* left;
Node* right;
Node();
Node(int data){
value = data;
left = NULL;
right = NULL;
}
};
void insert(Node* root , int val){
if(root == NULL){
root = new Node(val);
return;
}
if(root->value > val)
insert(root->left,val);
else
insert(root->right,val);
}
int main()
class Node* root = NULL;
insert(root,5);
cout<<root->value;
}
you are inserting position on the right place but the problem is you are not creating the link of your newly inserted node to it's parent.
you can check this as reference!

c++ - Will this cause any issues? Assigning a var using a function that passes itself as a parameter (hard for me to explain)

So it's very hard to explain so I'll just show it to you. I'm trying to implement a Red-Black tree in C++. Below is the code relevant to the question (complete code at this link)
I'm fairly new so please forgive me if I don't use the right terminology.
My question is about creating the root node. When a new value is added using addValue, it's assigning the new node to the root but at the same time is passing the root in as the parameter. I don't get any errors but it feels like this is not a good way to go about it.
enum colour {RED, BLACK, DOUBLEBLACK};
struct Node{
int data;
int colour;
Node *left, *right, *parent;
explicit Node(int);
};
class Tree{
public:
Tree();
virtual ~Tree(){};
void addValue(int);
Node* insertNode(Node *, Node*);
private:
Node* root;
};
Node::Node(int data) {
this->data = data;
colour = RED;
left = right = parent = nullptr;
}
Tree::Tree() {
root = nullptr;
}
void Tree::addValue(int n) {
Node *node = new Node(n);
root = insertNode(root, node); //*********** this line here
insertFix(node);
}
Node* Tree::insertNode(Node* root, Node* node) {
if (root == nullptr)
return node;
if(node->data < root->data) {
root->left = insertNode(root->left, node);
root->left->parent = root;
} else if (node->data > root->data) {
root->right = insertNode(root->right, node);
root->right->parent = root;
}
return root;
}

C++ binary tree object, "insert" method with 1 parameter

I'm learning binary trees and want to implement with OOP where I have a struct Node and create a BST Object. I'm trying to create an insert function with this approach and am running into the issue where I can't recursively traverse the tree to add a new node - that is, unless I overload the method, essentially copying it, to call the new method with a pointer to left or right. Hard to explain, but right now I have two methods, and I'm not sure if I'm missing something obvious to just have 1 method with 1 parameter int data, or if this approach just isn't correct. I feel like there's something valuable for me to learn here. Many thanks.
#include <iostream>
struct Node
{
Node *right;
Node *left;
int data;
};
class BST
{
public:
Node* root;
public:
BST()
:root(NULL)
{
}
//inserts node taking parameter data
Node* insertNode(int data)
{
//if tree is empty, create root
if (root == NULL)
{
root = newNode(data);
}
//if data is smaller than or equal to root, insert left
else if (data <= root->data)
{
root->left = insertNode(root->left, data);
}
//data is larger than root, insert right
else
{
root->right = insertNode(root->right, data);
}
return root;
}
//inserts new node
Node* insertNode(Node *root, int data)
{
//if tree is empty, create root
if (root == NULL)
{
root = newNode(data);
}
//if data is smaller than or equal to root, insert left
else if (data <= root->data)
{
root->left = insertNode(root->left, data);
}
//data is larger than root, insert right
else
{
root->right = insertNode(root->right, data);
}
return root;
}
Node* newNode(int data)
{
Node *temp = new Node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
};
int main() {
BST bst1;
bst1.insertNode(30);
bst1.insertNode(15);
return 0;
}
You can save the redundancy by having one call forward to the other:
Node* insertNode(int data)
{
return insertNode(root, data);
}
Note that having identical names for your class member (Node* root) and the local variable in Node* insertNode(Node *root, int data) is error-prone.
Also please do not forget to delete what you new.

create a BST of string . error

Inserting just one node to the tree works fine, but on inserting the 2nd node onwards, the program crashes. Here is the code:
#include <iostream>
#include <cstring>
using namespace std;
struct node
{
char* key;
node *left, *right;
};
// A utility function to create a new BST node
node *newNode(const char* item)
{
node *temp =new node;
strcpy(temp->key,item);
temp->left = temp->right = NULL;
return temp;
}
// A utility function to do inorder traversal of BST
void inorder(node *root)
{
if (root!= NULL)
{
inorder(root->left);
cout<<root->key<<endl;
inorder(root->right);
}
}
/* A utility function to insert a new node with given key in BST */
node* insert(node* tnode,const char* key)
{
/* If the tree is empty, return a new node */
if (tnode == NULL)
return newNode(key);
/* Otherwise, recur down the tree */
if (strcmp(key,tnode->key) < 0)
tnode->left = insert(tnode->left, key);
else if (strcmp(key,tnode->key) > 0)
tnode->right = insert(tnode->right, key);
/* return the (unchanged) node pointer */
return tnode;
}
// Driver Program to test above functions*/
int main()
{
node *root = NULL;
char* word[]={"elephant","hi","little","nil",NULL};
root = insert(root,word[0]); //works fine
for(int i=1;word[i];i++)
insert(root,word[i]);
// print inoder traversal of the BST
inorder(root);
return 0;
}
after:
root = insert(root,word[0]);
inorder(root);
o/p: elephant
on inserting 2nd node
crashes
You're not initialising the key array that item will get copied into. Try this:
node *newNode(const char* item)
{
node *temp = new node();
temp->key = new char[strlen(item) + 1];
strcpy(temp->key,item);
temp->left = temp->right = NULL;
return temp;
}
That said, there are some more problems with your code, like no destructors etc. I'd strongly recommend reading some good books/tutorials on programming in C++.

DFS in C++: return node if it contains searched key

My program goal is to search for a tree node with a given key using depth-first search and if a node with that key is found it will be returned to the caller function. The problem is that accessing the node after DFS execution terminates the program with a segmentation fault, exactly when it searches for a node in the right subtree, but not when searching on the left subtree.
This is the source code:
#include <iostream>
using namespace std;
struct node
char data;
struct node *left;
struct node *right;
};
struct node *root = nullptr;
struct node* addNewNode(char newData) {
struct node* newNode = new node;
newNode->data = newData;
newNode->left = nullptr;
newNode->right = nullptr;
return newNode;
}
struct node* preOrder(struct node *srcNode, char key) {
if (srcNode != nullptr) {
if (srcNode->data == key)
return srcNode;
return preOrder(srcNode->left, key);
return preOrder(srcNode->right, key);
}
}
int main() {
root = addNewNode('a');
root->left = addNewNode('e');
root->right = addNewNode('c');
root->left->left = addNewNode('h');
root->left->right = addNewNode('z');
struct node* res = preOrder(root, 'c');
cout << res->data;
return 0;
}
Your preOrder function does not always return a value. If srcNode is nullptr you should return nullptr.
Your compiler should be warning you about this! If it is not, then change your compiler settings, or get a better compiler.
Edit: Also - you should check that res is not nullptr before you try to use it.
Edit2: Didn't see this bit
return preOrder(srcNode->left, key);
return preOrder(srcNode->right, key);
The second call to preOrder will never be called (because you have already returned), so you are never searching right hand nodes. You need to change the logic so it search on the right hand node if the left search returned nullptr.