Iterative BST insertion in C++ - c++

I am trying to understand BSTs and how to insert elements into it iteratively. My node structure implementation looks like so:
struct Node{
Node *left;
Node *right;
T data; //template class
};
And my insertion implementation looks like so:
template<typename T>
bool BST<T>::Insert(const T value)
{
Node *newNode = new Node;
newNode -> data = value;
newNode -> left = NULL;
newNode -> right = NULL;
if(root == NULL) {root = newNode;} //If the BST is empty
else
{//The BST is not empty
Node *ptr = root; //points to the current Node
Node *ptr_parent; //points to the parent Node
while(ptr != NULL)
{
if((ptr -> data) > value)
{
ptr_parent = ptr;
ptr = ptr -> left;
}
if((ptr -> data) < value)
{
ptr_parent = ptr;
ptr = ptr -> right;
}
}
}
ptr = newNode; //insert the newNode at the spot
if((ptr_parent -> data) < value)
ptr_parent -> right = newNode;
else
ptr_parent -> left = newNode;
return true;
}
The insertion works when adding the first Node into an empty tree but I get a segmentation fault whenever i try to add more Nodes. I understand that there are posts that show how to implement insertions into BSTs but most of them show the recursive method, and those with iterative examples are incomplete or too specific. Thank you.

I think I'd do things a little differently. First, I'd simplify the other code a little by adding a ctor to the Node class:
struct Node{
Node *left;
Node *right;
T data;
Node(T const &data) : left(nullptr), right(nullptr), data(data) {}
};
Then you can use a pointer to a pointer to traverse the tree and insert the item:
bool insert(const T value) {
Node **pos;
for (pos = &root; *pos != nullptr;) {
if (value < (*pos)->value)
pos = &(*pos)->left;
else if ((*pos)->value < value )
pos = &(*pos)->right;
else
return false;
}
*pos = new Node(value);
return true;
}
Note that I've delayed creating the new node until after we've dropped out of the loop. This way, if we have a duplicate element, we can just return (without leaking a node, since we haven't allocated a new node yet).
For what it's worth, if you were going to do this recursively, it would probably be easier to use a reference to a pointer instead of a pointer to a pointer.

I was able to make my original code work last night, I'm sharing the answer here:
template<typename T>
bool BST<T>::Insert(const T value)
{
Node *ptr;
Node *ptr_parent;
if(root == NULL)
{//The BST is Empty...
Node *newNode = new Node;
newNode -> data = value;
newNode -> left = NULL;
newNode -> right = NULL;
root = newNode;
ptr = root;
} else { //traversing the tree to find the insertion point
ptr = root;
while(ptr != NULL)
{
if((ptr -> data) == value) {return false;} //to check for duplicates
if(value < (ptr -> data))
{
ptr_parent = ptr;
ptr = ptr -> left;
} else {
ptr_parent = ptr;
ptr = ptr -> right;
}
}
Node *newNode = new Node;
newNode -> data = value;
newNode -> left = NULL;
newNode -> right = NULL;
//checking for parent value to determine if
//the Node is a left or right child
if(value < (ptr_parent -> data))
ptr_parent -> left = newNode;
else
ptr_parent -> right = newNode;
}
++count;//to keep track of the Node count
return true;
}
For my own sake I wanted to solve this without using double pointers.

You didn't handle the case when ptr->data == value so the loop will be infinite whenever a duplicate is found, and ptr = newNode doesn't do anything, it just makes ptr point to newNode. Try this
//ptr holds the address of pointers to nodes.
Node **ptr = &root;
while(*ptr != NULL){
if((*ptr)->data > T)
ptr = &(*ptr)->right;
else
ptr = &(*ptr)->left;
//Not handling duplicates
}
//Change the value of the pointer to newNode
*ptr = newNode;

Use hard pointers
Node **ptr = &root; //points to the current Node
Node **ptr_parent; //points to the parent Node
When you are trying to do this
ptr = newNode; //insert the newNode at the spot
it doesn't do anyithing because you need to modify the pointer which points to the left or the right subnode
something like this:
template<typename T>
bool BST<T>::Insert(const T value)
{
Node *newNode = new Node;
newNode -> data = value;
newNode -> left = NULL;
newNode -> right = NULL;
if(root == NULL) {root = newNode;} //If the BST is empty
else
{//The BST is not empty
Node **ptr = &root; //points to the current Node
Node **ptr_parent; //points to the parent Node
while((*ptr) != NULL)
{
if(((*ptr) -> data) > value)
{
ptr_parent = ptr;
ptr = &ptr -> left;
}
if(((*ptr) -> data) < value)
{
ptr_parent = ptr;
ptr = &ptr -> right;
}
}
}
(*ptr) = newNode; //insert the newNode at the spot
if(((*ptr_parent) -> data) < value)
(*ptr_parent) -> right = newNode;
else
(*ptr_parent) -> left = newNode;
return true;
}

As I understand, it is failing because of following line:
ptr = newNode; //insert the newNode at the spot
after the while loop your ptr is NULL otherwise you can not exit from the while loop. You are assigning a struct to NULL, which is not right.
Hopefully this helps. Everything else looks normal.

void insert(node* root, int value)
{
if (root == NULL)
{
root = new node;
root->data = value;
return;
}
while(!((root->data < value && root->right == NULL) || (root->data >= value && root->left == NULL)))
{
if (root->data < value)
root = root->right;
else
root = root->left;
}
if (root->data < value)
{
root->right = new node;
root->right->data = value;
} else
{
root->left = new node;
root->left->data = value;
}
}

template <class T>
class TreeNode{
private:
T data;
TreeNode<T>* right,*left;
public:
void setData(T d){
this->data =d;
}
T getData(){
return this->data;
}
void setRight(TreeNode<T>* r){
this->right =r;
}
TreeNode<T>* getRight(){
return this->right;
}
void setLeft(TreeNode<T>* r){
this->left =r;
}
TreeNode<T>* getLeft(){
return this->left;
}
static TreeNode<T>* newNode(T data){
TreeNode<T>* n = new TreeNode<T>();
n->setData(data);
n->setRight(NULL);
n->setLeft(NULL);
return n;
}
};
template <class T>
class BinaryTree{
private:
TreeNode<T>* root;
public:
void insert(T data){
TreeNode<T>* n = TreeNode<T>::newNode(data);
if(root==NULL)
root = n;
else{
TreeNode<T>* t = root;
while(t!=NULL){
if(n->getData() >= t->getData()){
if(t->getRight()==NULL){
t->setRight(n); //newnode attached as right child in tree
t = NULL;
}
else
t = t->getRight();
}
else{
if(t->getLeft()==NULL){
t->setLeft(n); //newnode attached as left child in tree
t=NULL;
}
else
t = t->getLeft();
}
}
}
}
void preorder(){
TreeNode<T>* t = root;
preorderUtil(t);
}
void preorderUtil(TreeNode<T>* node){
if(node==NULL)
return;
preorderUtil(node->getLeft());
cout<<node->getData()<<" ";
preorderUtil(node->getRight());
}
};
I answered a case here Binary Search Tree insertion doesn't work see if it helps

void insert(int val)
{
Node *newNode;
newNode=new Node;
newNode->data=val;
Node *currentNode=root;
Node *parentNode;
if(root==NULL)
{
newNode->left=NULL;
newNode->right=NULL;
}
else
{
while(currentNode!=NULL)
{
if((currentNode->data)>val)
{
parentNode=currentNode;
currentNode=currentNode->left;
}
if((currentNode->data)<val)
{
parentNode=currentNode;
currentNode=currentNode->right;
}
}
}
currentNode=newNode;
if((parentNode->data)<val)
{
parentNode->right=newNode;
}
else
{
parentNode->right=newNode;
}
}

Related

C++ Linked list, program stuck when calling the next pointer in the list

I have made a linked list with c++.
I have no idea when trying to point to the next element of the list, the program stops.
My Node Class as follows:
class Node {
friend class List;
private :
Node* next;
public:
int value;
Node()
{
value = 0;
next = nullptr;
}
Node(int data)
{
this->value = data;
this->next = nullptr;
}
};
My List class has next and delete methods. Whenever there is calling for the next attributes in the Node class. The program stucks.
For my List Class I made them as follows:
class List {
private:
Node* head;
public:
List ()
{
head = 0; // create an empty list
}
~List ()
{
delete head; // clean up the list and all nodes
}
Node* first () const
{
return head;
}
Node* next(const Node* n) const{
return n->next;
}
void append(int i)
{
Node* newNode = new Node(i);
if (head == nullptr){
head = newNode;
}
else
{
Node *ptr = head;
// the loop sets ptr to last node of the linked list
while (ptr->next != nullptr){
ptr = ptr->next;
}
// ptr now points to the last node
// store temp address in the next of ptr
ptr->next = newNode;
}
}
void insert(Node* n, int i)
{
Node *ptr = head;
Node *newNode = new Node(i);
newNode->next = n;
if(n==head)
{
head = newNode;
}
else
{
while(ptr->next != n)
{
ptr = ptr->next;
}
ptr->next = newNode;
}
}
void erase( Node* n)
{
Node *ptr = head;
Node *before ;
if (n->next == nullptr)
{
free(n);
return ;
}
if(head == n)
{
head = n->next;
free(n);
return ;
}
else
{
while(ptr!= n)
{
before = ptr;
ptr = ptr->next ;
}
before->next = ptr;
free(ptr);
free(n);
return ;
}
}
void printLst()
{
while(head != nullptr)
{
std::cout<<head->value<<" ";
head = head->next;
}
}
};
and to get a full vision of program. I made the main function very simple:
int main()
{
List list;
list.append(55);
list.append(50);
list.append(20);
list.append(30);
list.insert(list.first(), 22);
list.insert(list.first(), 87);
list.printLst();
list.erase(list.first());
list.printLst();
}
Any suggestions ?
in erase you never assign a value to 'before'
Node* before;
then you do
before->next = ptr;
Error C4703 potentially uninitialized local pointer variable 'before' used ConsoleApplication1 C:\work\ConsoleApplication1\ConsoleApplication1.cpp 124
also - more importantly your printLst function sets head to null
void printLst()
{
while (head != nullptr)
{
std::cout << head->value << " ";
head = head->next; <<========
}
}
your print function should not change head
so list.first then returns null so this
list.erase(list.first());
calls erase with null
Exception thrown: read access violation.
n was nullptr.

Segmentation Fault coming "Insertion in Binary Search tree." #

I am writing a function to insert a node in BST,but getting segmentation fault.
/*
Node is defined as
typedef struct node
{
int data;
node * left;
node * right;
}node;
*/
node * findPos(node * tree, int value){
if(tree -> data > value){
return findPos(tree -> left, value);
}
else if (tree -> data < value){
return findPos(tree -> right, value);
}
return tree;
}
node * addNode(int value){
struct node * temp =(struct node *)malloc(sizeof(struct node));
temp->data = value;
temp->left = NULL;
temp -> right = NULL;
return temp;
}
node * insert(node * root, int value)
{
node * ptr = root;
if(ptr == NULL)
return addNode(value);
else if(ptr -> data > value){
ptr->left = findPos(ptr -> left, value);
}
else if(ptr -> data < value){
ptr->right = findPos(ptr -> right, value);
}
return root;
}
i am not able to understand which illegal memory i am trying to access which is giving this error.
Please help me with this.
Thanks in advance :)
Thanks for the help guys!!!
got the program working
/*
Node is defined as
typedef struct node
{
int data;
node * left;
node * right;
}node;
*/
node * addNode(int value){
struct node * temp =(struct node *)malloc(sizeof(struct node));
temp->data = value;
temp->left = NULL;
temp -> right = NULL;
return temp;
}
node * insert(node * root, int value)
{
node * ptr = root;
if(ptr == NULL)
return addNode(value);
else if(ptr -> data > value){
ptr->left = insert(ptr -> left, value);
}
else if(ptr -> data < value){
ptr->right = insert(ptr -> right, value);
}
return root;
}
There are two issues here:
findPos should handle the case in which tree is NULL.
insert should not recursively call findPos. Instead it should recursively call insert. Something like this (haven't tested it):
node * insert(node * root, int value)
{
node * ptr = root;
if(ptr == NULL)
return addNode(value);
else if(ptr -> data > value) {
return insert(ptr -> left, value);
} else if(ptr -> data < value) {
return insert(ptr -> right, value);
} else
return root;
}

remove item on linked list

I have implemented a linked list but I find that removal of the last element in the linked list always fails. I checked my code several times but didn't find the logic mistake. Remove from the head and middle node works fine. Below is my code:
#include<iostream>
using namespace std;
template<typename T>
class Node{ //
private:
T val;
Node *next;
Node *prev;
public:
Node(T value){
val = value;
next = nullptr;
prev = nullptr;
}
~Node(){
if(prev != nullptr){
prev->next = next;
}
if(next != nullptr){
next->prev= prev;
}
}
T& getVal(){ //
return val;
}
Node* getNext(){
return next;
}
Node* getPrev(){
return prev;
}
//insert node after this node
void insert(Node *n){
if(next != nullptr){
next->prev = n;
}
n->next = next;
n->prev = this;
next = n;
}
void deleteNode(){
if(prev != nullptr && next != nullptr){
prev->next = next;
next->prev = prev;
}
}
};
//build a linked list with deletion and push back function
template<typename T>
class LList{
private:
Node<T> *head;
Node<T> *tail;
public:
LList(){
head = nullptr;
tail = nullptr;
}
~LList(){
if(nullptr != head){
while(head->getNext() != nullptr){ //
delete head->getNext();
}
delete head;
}
}
void push_back(T val){
Node<T>* n = new Node<T>(val);
if(head == nullptr){
head = n ;
tail = head;
}
else{
tail->insert(n);
tail = n;
}
}
void deleteItem(T item){
Node<T> *node = head;
//delete head
if(node->getVal() == item){
head = node->getNext();
node->deleteNode();
return;
}
//delete middle and tail
while(node->getVal() != item && node->getNext() != nullptr ){
node = node->getNext();
}
if(node->getVal() == item && node == tail){
tail = node->getPrev();
node->deleteNode();
return;
}
if(node->getVal() == item && node != tail){
node->deleteNode();
return;
}
else {
cout<<"didnt find the item "<<item<<endl;
}
}
void print(){
Node<T> *node = head;
while(node->getNext() != nullptr){
cout<<node->getVal()<<endl;
node = node->getNext();
}
cout<<node->getVal()<<endl;
}
};
int main(){
LList<double> list;
list.push_back(3.13);
list.push_back(2.8);
list.push_back(23);
list.push_back(4);
list.print();
list.deleteItem(3.13);
list.deleteItem(2);
list.deleteItem(4);
list.print();
return 0;
}
Here it is:
void deleteNode(){
if(prev != nullptr && next != nullptr){
prev->next = next;
next->prev = prev;
}
}
};
For the last element i guess that next equals nullptr and so the whole condition fails.
What I don't understand, is why removing the first element doesn't fail too, you probably should x-check your code for this.
[edit]
Here's my solution to fix this bug, it's basically the same as in the destructor for node:
void deleteNode(){
if(prev != nullptr){
prev->next = next;
}
if(next != nullptr){
next->prev= prev;
}
};
I think all cases have been considered in this:
Head := prev == null & next->prev = nullptr (assuming prev for this node was nullptr before)
Middle := prev->next = next & next->prev = prev
Tail := prev->next = null (assuming as above) & next == null
Head&Tail := prev == null & next == null (Only element of the list is deleted, so no references to be changed)
[/edit]

Deleting a node with only one child from a Binary Search Tree

This is a code to delete a node from a Binary Search Tree:
My question is: Why do we pass the node pointer by reference to DelSingle function but we only pass a node pointer to DelDoubleByCopying function?
template <class T>
bool BST<T>::DeleteNode(T& val)
{
BSTNode<T> * node = root, *prev = NULL;
if (IsEmpty() == true)
return false;
while (node != NULL)
{
if (node->val == val)
break;
prev = node;
if (val < node->val)
node = node->left;
else
node = node->right;
}
if (node == NULL)
return false;
if (node->left == NULL || node->right == NULL)
{
if (node == root)
DelSingle(root);
else if(node == prev->left)
DelSingle(prev->left);
else
DelSingle(prev->right);
}
else
DelDoubleByCopying(node);
return true;
}
template <class T>
void BST<T>::DelSingle(BSTNode<T>*& ptr)
{
BSTNode<T>* delNode = ptr;
if(delNode->left == NULL) // node does not have a left child
ptr = delNode->right;
else if(delNode->right == NULL) // node does not have a right child
ptr = delNode->left;
delete delNode;
}
template <class T>
void BST<T>::DelDoubleByCopying(BSTNode<T>* node)
{
BSTNode<T> *prev, *rep;
rep = node->left; //Find the largest child in the left subtree
prev = node;
while (rep->right != NULL)
{
prev = rep;
rep = rep->right;
}
node->val = rep->val;
if (prev == node)
prev->left = rep->left;
else
prev->right = rep->left;
delete rep;
}
And this is the class of Binary Search Tree node:
template <class T>
class BSTNode
{
public:
BSTNode(T& val, BSTNode* left, BSTNode* right);
~BSTNode();
T GetVal();
BSTNode* GetLeft();
BSTNode* GetRight();
private:
T val;
BSTNode* left;
BSTNode* right;
int depth, height;
friend class BST<T>;
};
DelSingle()
Given the follwing structure
parent
ptr1 ptr2
child1
And sssuming we are deleting ptr1:
Basically, what DelSingle() does is to swap child1 with ptr1 and then get ride of child1 (child1 is not what ptr1 once was).
ptr is passed by reference because you are actually changing the pointer, parent's left child is not child1.
DelDoubleByCopying()
You don't need to pass node by reference because node is not going to change, the one who changes is node->left (or node->right).

Recursive Reverse Single Linked List

I am trying to just write a basic function that reverses a singly-linked list which is recursive. I was wondering if i tackled this in the right approach? Maybe someone can give me some pointers.
void reverse(Node*& p) {
if (!p) return;
Node* rest = p->next;
if (!rest) return;
reverse(rest);
p->next->next = p;
p->next = NULL;
p = rest;
}
That's not the most efficient way, but to do it, you can call the reverse method with the "next" pointer until there is no next. Once there, set next to previous. After returning from the recursion, set next to previous. See the recursive version here for an example. From the link:
Node * reverse( Node * ptr , Node * previous)
{
Node * temp;
if(ptr->next == NULL) {
ptr->next = previous;
previous->next = NULL;
return ptr;
} else {
temp = reverse(ptr->next, ptr);
ptr->next = previous;
return temp;
}
}
reversedHead = reverse(head, NULL);
This might be helpful
List
{
public:
.....
void plzReverse()
{
Node* node = myReverse(head);
node->next = NULL;
}
private:
Node * myReverse(Node * node)
{
if(node->next == NULL)
{
head = node;
return node;
}
else
{
Node * temp = myReverse(node->next);
temp ->next = node;
return node;
}
}
}
Another solution might be:
List
{
public:
.....
void plzReverse()
{
Node* node = myReverse(head, head);
node->next = NULL;
}
private:
Node * myReverse(Node * node, Node*& rhead)
{
if(node->next == NULL)
{
rhead = node;
return node;
}
else
{
Node * temp = myReverse(node->next,rhead);
temp ->next = node;
return node;
}
}
}
This is what you need:
Node* reverse(Node* p) {
if (p->next == NULL) {
return p;
} else {
Node* t = reverse(p->next); // Now p->next is reversed, t is the new head.
p->next->next = p; // p->next is the current tail, so p becomes the new tail.
p->next = NULL;
return t;
}
}
The recursive solution can look quite pretty, even in C++:
Node* reverse(Node* pivot, Node* backward = 0) {
if (pivot == 0) // We're done
return backward;
// flip the head of pivot from forward to backward
Node* rest = pivot->next;
pivot->next = backward;
// and continue
return reverse(rest, pivot);
}
Most C++ compilers do tail call optimization so there's no reason to believe this to be less efficient than an iterative solution.
Here is the solution that preserves return value as void.
void reverse(Node*& p) {
if (!p) return;
Node* rest = p->next;
if (!rest) {
rest = p;
return;
}
reverse(rest);
p->next->next = p;
p->next = NULL;
p = rest;
}
linkedList *reverseMyNextPointer(linkedList *prevNode, linkedList *currNode)
{
linkedList *tempPtr;
if(!currNode)
return prevNode;
else
{
tempPtr = currNode->next;
currNode->next = prevNode;
return reverseMyNext(currNode,tempPtr);
}
}
head = reverseMyNextPointer(nullptr,head);