I've got a non-recursive pseudocode for deleting a node (without 2 children case at the moment), which I have to implement. Everything seems to be OK, except the situation when I want to delete a root.
The pseudocode:
delete(root, key)
{
parent = NULL;
p = root; //p - node to delete
while( (p != NULL) && (key != p->data) )
{
parent = p;
if( p->data < key ) p = p->right;
else p = p->left;
}
if( p == NULL ) return;
if( (p->right == NULL) && (p->left == NULL) ) // deleted node p is a leaf
{
if(p == root)
{
root = NULL; // deleted leaf is a root
return;
}
if( parent->right == p) parent->right = NULL;
else parent->left = NULL;
return;
}
if( p->right == NULL ) // p node to delete has only left subtree
{
if( parent->right == p ) parent->right = p->left;
else parent->left = p->left;
return;
}
if( p->left == NULL ) // p node to delete has only right subtree
{
if( parent->right == p ) parent->right = p->right;
else parent->left = p->right;
return;
}
}
And here is my implementation:
struct BstNode
{
int data;
BstNode *left, *right;
};
void Remove(BstNode **root, int key)
{
BstNode **parent, ***p;
parent=NULL;
p=&root;
while((**p!=NULL) && (key!=(**p)->data))
{
parent=&(**p);
if((**p)->data < key) *p=&(**p)->right;
else *p=&(**p)->left;
}
if((**p)==NULL)
{
cout << "no such element! " <<endl;
return;
}
if(((**p)->right)==NULL && (**p)->left==NULL)
{
if((**p)==*root)
{
*root=NULL;
return;
}
if((*parent)->right==(**p))
(*parent)->right = NULL;
else (*parent)->left = NULL;
return;
}
if(((**p)->right)==NULL )
{
if((*parent)->right== (**p))
(*parent)->right = (**p)->left;
else
(*parent)->left = (**p)->left;
return;
}
if(((**p)->left)==NULL )
{
if((*parent)->right==(**p))
(*parent)->right = (**p)->right;
else
(*parent)->left = (**p)->right;
return;
}
}
int main()
{
BstNode* root = NULL;
Insert(&root,2);
/* ... */
Remove(&root,2);
}
I believe that there's something wrong with "parent", because root has no parent. However, I have no idea how to find a way round this problem.
Related
I've pasted my whole code below.
I'm able to delete node successfully with no child or one child but unable to delete node with two children.
In node with two children I'm using approach where I swap the value of targeted node with it's leaf child and then trying to delete the leaf node.
But while deleting it's giving error exited with code=3221225725 in 0.474 seconds I also tried creating other functions to delete it but end up getting the same.
I've tried removing delete and the code is running just fine and the value is swapped successfully too! I've also used same approach for Binary Search Tree and it was working just fine!
#include <iostream>
class BinaryTree
{
struct Node
{
int data;
Node *left_child;
Node *right_child;
};
Node *root;
Node *appendage(Node *root, int data)
{
if (root == NULL)
{
root = new Node();
root->data = data;
root->left_child = NULL;
root->right_child = NULL;
return root;
}
else if (root->left_child == NULL and root->right_child == NULL)
{
root->left_child = appendage(root->left_child, data);
}
else if (root->left_child != NULL and root->right_child == NULL)
{
root->right_child = appendage(root->right_child, data);
}
else
{
root->left_child = appendage(root->left_child, data);
}
return root;
}
Node *deletion(Node *root, int data)
{
if (root == NULL)
{
return root;
}
else if (data != root->data)
{
root->left_child = deletion(root->left_child, data);
root->right_child = deletion(root->right_child, data);
}
else
{
if (root->left_child == NULL && root->right_child == NULL)
{
delete root;
return NULL;
}
else if (root->left_child == NULL)
{
Node *temp_node = root;
root = root->right_child;
delete temp_node;
}
else if (root->right_child == NULL)
{
Node *temp_node = root;
root = root->left_child;
delete temp_node;
}
//////// ***ERROR BELOW (DUE TO DELETE)***
else //DELETE WITH TWO NODES
{
Node *temp_node = last_right_node(root);
root->data = temp_node->data;
delete temp_node;
}
//////// ***ERROR ABOVE (DUE TO DELETE)***
}
return root;
}
void inorder_display(Node *root)
{
if (root == NULL)
{
return;
}
inorder_display(root->left_child);
std::cout<<root->data<<" ";
inorder_display(root->right_child);
}
void preorder_display(Node *root)
{
if (root == NULL)
{
return;
}
std::cout<<root->data<<" ";
preorder_display(root->left_child);
preorder_display(root->right_child);
}
void postorder_display(Node *root)
{
if (root == NULL)
{
return;
}
postorder_display(root->left_child);
postorder_display(root->right_child);
std::cout<<root->data<<" ";
}
Node *destroy_tree(Node *root)
{
if (root != NULL)
{
destroy_tree(root->left_child);
destroy_tree(root->right_child);
delete root;
}
return root;
}
Node *last_right_node(Node *root)
{
if (root == NULL)
{
return root;
}
else if (root->right_child == NULL)
{
return root;
}
else
{
return last_right_node(root->right_child);
}
};
public:
BinaryTree()
{
root = NULL;
}
void append(int data)
{
root = appendage(root, data);
}
void remove(int data)
{
deletion(root,data);
}
void inorder()
{
inorder_display(root);
std::cout<<"\n";
}
void preorder()
{
preorder_display(root);
std::cout<<"\n";
}
void postorder()
{
postorder_display(root);
std::cout<<"\n";
}
int last()
{
return last_right_node(root)->data;
}
~BinaryTree()
{
destroy_tree(root);
}
};
int main()
{
BinaryTree b;
b.append(1);
b.append(2);
b.append(3);
b.append(4);
b.append(5);
b.inorder();
b.preorder();
b.postorder();
//std::cout<<b.last();
b.remove(2);
b.inorder();
return 0;
}
I'm going to post a section in Java, but I assume if you're doing BinaryTrees you can read it haha. Anyways, it looks like you have Node defined which is equivilent to my BinaryTreeNode<T> and then you want to have a constructor that takes in a left and right tree node to recursively define the tree.
protected BinaryTreeNode<T> _root = null ;
public LinkedBinaryTree() {}
public LinkedBinaryTree( T element )
{
_root = new BinaryTreeNode<T>( element ) ;
}
public LinkedBinaryTree( T element,
LinkedBinaryTree<T> left, LinkedBinaryTree<T> right )
{
_root = new BinaryTreeNode<T>( element ) ;
_root.setLeft( left.getRootNode() ) ;
_root.setRight( right.getRootNode() );
}
public BinaryTreeNode<T> getRootNode() { return _root ; }
That might help with redifining your structure.
I'll show my entire remove sections with a few comments. I think you might want to focus on the "//has 2 children" else clause and see what's happening; I'm too tired to compare ours (This is my binarySEARCHtree version)
public T removeElement(T target)
throws ElementNotFoundException
{
if( isEmpty() )
throw new ElementNotFoundException() ;
T result = null ;
if( target.equals( _root.getElement() ) )
{
result = _root.getElement() ;
BinaryTreeNode<T> temp = replacement( _root ) ;
if( temp == null )
_root = null ;
else
{
_root.setElement( temp.getElement() );
_root.setLeft( temp.getLeft() ) ;
_root.setRight( temp.getRight() ) ;
}
}
else
{
BinaryTreeNode<T> parent = _root ;
if( target.compareTo( _root.getElement() ) < 0 )
result = removeElement( target, _root.getLeft(), parent ) ;
else
result = removeElement( target, _root.getRight(), parent ) ;
}
return result ;
}
/** #child of #removeElement( T target ) */
private T removeElement( T target, BinaryTreeNode<T> node, BinaryTreeNode<T> parent )
{
if( node == null )
throw new ElementNotFoundException() ;
T result = null ;
if( target.equals( node.getElement() ) )
{
result = node.getElement() ;
BinaryTreeNode<T> temp = replacement( node ) ;
if( parent.getRight() == node )
parent.setRight(temp) ;
else
parent.setLeft( temp ) ;
}
else
{
parent = node ;
if( target.compareTo(node.getElement()) < 0 )
result = removeElement( target, node.getLeft(), parent ) ;
else
result = removeElement( target, node.getRight(), parent ) ;
}
return result ;
}
/** #child of #removeElement */
private BinaryTreeNode<T> replacement( BinaryTreeNode<T> node )
{
BinaryTreeNode<T> result = null ;
if( ( node.getLeft() == null ) && ( node.getRight() == null ) )
{
result = null ;
}
else if( ( node.getLeft() != null ) && ( node.getRight() == null ) )
{
result = node.getLeft() ;
}
else if( ( node.getLeft() == null ) && ( node.getRight() != null ) )
{
result = node.getRight() ;
}
else
{ //has 2 children
BinaryTreeNode<T> parent = node ;
BinaryTreeNode<T> current = node.getRight() ;
while( current.getLeft() != null )
{
parent = current ;
current = parent.getLeft() ;
}
current.setLeft( node.getLeft() ) ;
if( node.getRight() != current )
{
parent.setLeft(current.getRight() ) ;
current.setRight( node.getRight() ) ;
}
result = current ;
}
return result ;
}
I've changed the last right node function where it returns parent of leaf node.
I've linked children of targeted node with last right node (leaf node) and then after removing it from it's parent node I swap it with the targeted node!
It works fine with all the cases!
/*
Depth First Traversals:
(a) Inorder (Left, Root, Right) : 4 2 5 1 3
(b) Preorder (Root, Left, Right) : 1 2 4 5 3
(c) Postorder (Left, Right, Root) : 4 5 2 3 1
*/
#include <iostream>
class BinaryTree
{
struct Node
{
int data;
Node *left_child;
Node *right_child;
};
Node *root;
//////// *** CHANGES BELOW HERE ***
Node *last_right_node(Node *root)
{
Node *parent_node = root;
if ((root->right_child)->right_child == NULL)
{
return parent_node;
}
return last_right_node(root->right_child);
}
//////// *** CHANGES ABOVE HERE ***
Node *appendage(Node *root, int data)
{
if (root == NULL)
{
root = new Node();
root->data = data;
root->left_child = NULL;
root->right_child = NULL;
return root;
}
else if (root->left_child == NULL and root->right_child == NULL)
{
root->left_child = appendage(root->left_child, data);
}
else if (root->left_child != NULL and root->right_child == NULL)
{
root->right_child = appendage(root->right_child, data);
}
else
{
root->left_child = appendage(root->left_child, data);
}
return root;
}
Node *deletion(Node *root, int data)
{
if (root == NULL)
{
return root;
}
else if (data != root->data)
{
root->left_child = deletion(root->left_child, data);
root->right_child = deletion(root->right_child, data);
}
else
{
if (root->left_child == NULL && root->right_child == NULL)
{
delete root;
return NULL;
}
else if (root->left_child == NULL)
{
Node *temp_node = root;
root = root->right_child;
delete temp_node;
}
else if (root->right_child == NULL)
{
Node *temp_node = root;
root = root->left_child;
delete temp_node;
}
//////// *** SOLVED BELOW ***
else
{
// PARENT NODE OF LEAF NODE
Node *temp_node = last_right_node(root);
// LEAF NODE
Node *leaf_node = temp_node->right_child;
// REMOVING LEAF NODE FROM TREE
temp_node->right_child = NULL;
// LINKING LEAF NODE WITH TARGET NODE CHILDREN
leaf_node->left_child = root->left_child;
leaf_node->right_child = root->right_child;
// SWAPPING THE NODE
root = leaf_node;
}
//////// *** SOLVED ABOVE ***
}
return root;
}
void inorder_display(Node *root)
{
if (root == NULL)
{
return;
}
inorder_display(root->left_child);
std::cout<<root->data<<" ";
inorder_display(root->right_child);
}
void preorder_display(Node *root)
{
if (root == NULL)
{
return;
}
std::cout<<root->data<<" ";
preorder_display(root->left_child);
preorder_display(root->right_child);
}
void postorder_display(Node *root)
{
if (root == NULL)
{
return;
}
postorder_display(root->left_child);
postorder_display(root->right_child);
std::cout<<root->data<<" ";
}
Node *destroy_tree(Node *root)
{
if (root != NULL)
{
destroy_tree(root->left_child);
destroy_tree(root->right_child);
delete root;
}
return root;
}
public:
BinaryTree()
{
root = NULL;
}
void append(int data)
{
root = appendage(root, data);
}
void remove(int data)
{
root = deletion(root,data);
}
void inorder()
{
inorder_display(root);
std::cout<<"\n";
}
void preorder()
{
preorder_display(root);
std::cout<<"\n";
}
void postorder()
{
postorder_display(root);
std::cout<<"\n";
}
~BinaryTree()
{
destroy_tree(root);
}
};
int main()
{
BinaryTree b;
b.append(1);
b.append(2);
b.append(3);
b.append(4);
b.append(5);
b.inorder();
b.preorder();
b.postorder();
b.remove(1);
b.inorder();
return 0;
}
I am having difficulty releasing memory for my BST deletion. The algorithm itself works, so long as I don't include the "delete" keyword. As soon as I do, it causes this error: malloc: * error for object 0x7fec6a4026a0:
pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
Abort trap: 6
Here is my code, along with the single "delete" keyword. I've also included other locations where I've tried placing the delete keyword. I understand that you must free up the memory in C++ to prevent memory leaks. I have a feeling that the recursive call may be causing the problem, but I can't pinpoint it.
bool AVLTree::deleteNode(string ss, AVLNode* starting){
AVLNode* curr = starting;
AVLNode* parent = starting->parent;
while (curr != nullptr) {
if (curr->ssn == ss) {
// Remove leaf
if (curr->right == nullptr && curr->left == nullptr) {
// Remove root
if (parent == nullptr) {
root = nullptr;
}
else if (parent->left == curr) {
parent->left = nullptr;
}
else {
parent->right = nullptr;
}
// IVE TRIED PUTTING DELETE HERE
}
// Remove node with two children
else if (curr->right != nullptr && curr->left != nullptr) {
// Find succesor
AVLNode* succ = curr->right;
while (succ->left != nullptr) {
succ = succ->left;
}
// Copy
curr->ssn = succ->ssn;
curr->name = succ->name;
deleteNode(succ->ssn, curr->right);
}
// Remove node with one children
else {
// If has left child
if (curr->left != nullptr) {
if (parent == nullptr) {
root = curr->left;
}
else if (parent->left == curr) {
parent->left = curr->left;
}
else {
parent->right = curr->left;
}
}
else if (curr->right != nullptr) {
if (parent == nullptr) {
root = curr->right;
}
else if (parent->left == curr) {
parent->left = curr->right;
}
else {
parent->right = curr->right;
}
}
// IVE TRIED PUTTING DELETE HERE
}
delete curr; // THIS IS CAUSING THE PROBLEM
return true;
}
else if ((curr->ssn.compare(ss)) < 0) {
parent = curr;
curr = curr->right;
}
else {
parent = curr;
curr = curr->left;
}
}
return false;
}
// Insert function
bool AVLTree::insert(string ss, string na){
AVLNode* curr = root;
// Construct new AVL Node
AVLNode* newNode = new AVLNode(ss, na);
// If root is empty, insert
if (curr == nullptr) {
root = newNode;
return true;
}
while (curr != nullptr) {
if (curr->ssn.compare(newNode->ssn) == 0) {
delete newNode;
return false;
}
// Go right
if (newNode->ssn.compare(curr->ssn) > 0) {
// Check to see if we can insert, currs right child is null
if (curr->right == nullptr) {
curr->right = newNode;
newNode->parent = curr;
break;
}
else {
curr = curr->right;
}
}
// Go left
else {
// Check to see if we can insert
if (curr->left == nullptr) {
curr->left = newNode;
newNode->parent = curr;
break;
} else {
curr = curr->left;
}
}
}
return true;
}
I coded case #2 in delete_node but am getting a segmentation error. I'm using the predecessor to delete the node. I'm not sure what happens when I am removing the root node with two children. Is it the same as deleting a non-root node with two children except you don't have to connect the predecessor's children? I think that's how I've coded it...
bool delete_node(Node*& root, KType key) {
// find target node to delete
Node* target = find(key, root);
if (!target) return false;
// find parent of target
Node* parent = find_parent(root, target);
// case 1: target is a leaf
if (target->left == NULL && target->right == NULL) {
// set parent's child pointer
if (parent != NULL) {
if ( parent->left == target )
parent->left = NULL;
else
parent->right = NULL;
}
else
root = NULL;
// free target
delete target;
return true;
}
// case 2: target has two children
else if (target->left != NULL && target->right != NULL) {
if (parent != NULL) {
//find predecessor
Node* temp = target->left;
while (temp != NULL) {
temp = temp->right;
}
// find predecessor's parent
Node* predecessorParent = find_parent(root, temp);
target->key = temp->key;
if (predecessorParent->left == temp) {
predecessorParent->left = temp->left;
} else {
predecessorParent->right = temp->left;
}
delete(temp);
return true; // return true when you're done.
} else {
//find predecessor
Node* temp = target->left;
while (temp != NULL) {
temp = temp->right;
}
target->key = temp->key;
delete(temp);
return true; // return true when you're done.
}
}
// case 3: target has only left child
else if (target->left != NULL) {
// set parent's child pointer
if (parent != NULL) {
if ( parent->left == target )
parent->left = target->left;
else
parent->right = target->left;
}
else
root = target->left;
// free target
delete target;
return true;
}
// case 4: target has only right child
else {
// set parent's child pointer
if (parent != NULL) {
if (parent->left == target)
parent->left = target->right;
else
parent->right = target->right;
}
else
root = target->right;
// free target
delete target;
return true;
}
return false;
}
find_parent function:
/**
* Finds the parent of node in the tree rooted at rootNode
*/
Node* find_parent(Node* rootNode, Node* node) {
if ( rootNode == NULL || rootNode == node ) {
return NULL;
}
else if ( rootNode->left == node || rootNode->right == node ) {
return rootNode;
}
else if (node->key < rootNode->key) {
return find_parent(rootNode->left, node);
}
else {
return find_parent(rootNode->right, node);
}
}
Following is a piece of my code for deleting a node from a BST. It is a non-recursive code.
I have applied all the possible conditions.
However when I run my code, it stops as if stuck somewhere in an infinite loop or ending up at a point where my pointer is pointing to NULL.However I am unable to identify it.
Any help would be appreciated.
template <class T>
void bst<T>::delete_node(T key1)
bst_node<T>* delNode = search(key1); //delNode is the node I wish to delete
if(delNode!=root)
{
if((delNode->left == NULL) && (delNode->right == NULL)) // node to be deleted has no children
{
delNode = NULL;
}
else if((delNode->left!=NULL) && (delNode->right == NULL)) //node to be deleted has exactly one child
{
if(delNode->parent->left == delNode)
{
delNode->parent->left = delNode->left;
delNode = NULL;
}
else if(delNode->parent->right == delNode)
{
delNode->parent->right = delNode->left;
delNode = NULL;
}
}
else if((delNode->right!= NULL) && (delNode->left == NULL))
{
if(delNode->parent->left == delNode)
{
delNode->parent->left = delNode->right;
delNode = NULL;
}
else if(delNode->parent->right == delNode)
{
delNode->parent->right = delNode->right;
delNode = NULL;
}
}
else if((delNode->right!=NULL)&&(delNode->left != NULL)) //if has two children
{
bst_node<T>* temp = delNode;
bst_node<T>* trav = delNode->right;
if((trav->right == NULL)&&(trav->left == NULL))
{
delNode->value = trav->value;
delNode->key = trav->key;
trav = NULL;
}
else
{
bst_node<T>* pred = trav;
while(trav!=NULL)
{
pred = trav; //smallest node in right subtree
trav=trav->left;
}
delNode->value = pred->value;
delNode->key = pred->key;
pred = NULL;
}
}
}
else if(delNode==root)//node to be deleted is Root
{
if((delNode->left==NULL)&&(delNode->right==NULL))
root = NULL;
else if((delNode->left!=NULL) && (delNode->right == NULL)) //root has exactly one child
{
root = delNode->left;
delNode = NULL;
}
else if((delNode->right!= NULL) && (delNode->left == NULL))
{
root = delNode->right;
delNode = NULL;
}
else if((delNode->right!=NULL)&&(delNode->left!=NULL)) {
bst_node<T>* temp = delNode;
bst_node<T>* trav = delNode->right;
if((trav->right == NULL)&&(trav->left == NULL))
{
delNode->value = trav->value;
delNode->key = trav->key;
trav = NULL;
}
else
{
bst_node<T>* pred = trav;
while(trav!=NULL)
{
pred = trav; //smallest node in right subtree
trav=trav->left;
}
delNode->value = pred->value;
delNode->key = pred->key;
pred = NULL;
}
}
}
}
In the part:
else if((delNode->right!=NULL)&&(delNode->left != NULL)) //if has two children
when if is taken:
if((trav->right == NULL)&&(trav->left == NULL))
the code copies the values from trav to delNode and sets trav to NULL:
delNode->value = trav->value;
delNode->key = trav->key;
trav = NULL;
but doesn't set delNode->right to NULL, as it should because trav didn't have any children.
the very next else statement which seeks for the most left node commits a similar error, because parent node's member left isn't set to NULL.
The next big part of the code which deals with deletion of only root node, seems to have identical problems, due to apparent copy-pasted (cough!) code.
I have a very frustrated situation with my BST code:
vector<int> order;
BinarySearchTree tree;
for (int i=0; i<1000; ++i) {
int j = rand()%1000;
order.push_back(j);
}
for (int i = 0; i < 1000; ++i) {
tree.insert(order[i]);
}
while(!tree.isEmpty()) {
cout << tree.min() << endl;
tree.remove(tree.min());
}
the code is working perfectly fine with small number of i, say 10, or 100. However, it is stop working when i is 1000.
the insert function is as follows
void BinarySearchTree::insert(int d)
{
tree_node* t = new tree_node;
tree_node* parent;
t->data = d;
t->left = NULL;
t->right = NULL;
parent = NULL;
// is this a new tree?
if(isEmpty()) root = t;
else
{
//Note: ALL insertions are as leaf nodes
tree_node* curr;
curr = root;
// Find the Node's parent
while(curr)
{
parent = curr;
if(t->data > curr->data) curr = curr->right;
else curr = curr->left;
}
if(t->data <= parent->data)
parent->left = t;
else
parent->right = t;
}
}
In response to the comments, i am going to post all the code. :)
void BinarySearchTree::remove(int d)
{
//Locate the element
bool found = false;
if(isEmpty())
{
cout<<" This Tree is empty! "<<endl;
return;
}
tree_node* curr;
tree_node* parent;
curr = root;
//parent = root;
while(curr != NULL)
{
if(curr->data == d)
{
found = true;
break;
}
else
{
parent = curr;
if(d>curr->data) curr = curr->right;
else curr = curr->left;
}
}
if(!found)
{
cout<<" Data not found! "<<endl;
return;
}
// 3 cases :
// 1. We're removing a leaf node
// 2. We're removing a node with a single child
// 3. we're removing a node with 2 children
// Node with single child
if((curr->left == NULL && curr->right != NULL)|| (curr->left != NULL
&& curr->right == NULL))
{
if(curr->left == NULL && curr->right != NULL)
{
if (curr == root) {
root = curr->right;
delete curr;
}
else {
if(parent->left == curr)
{
parent->left = curr->right;
delete curr;
}
else
{
parent->right = curr->right;
delete curr;
}
}
}
else // left child present, no right child
{
if (curr==root) {
root = curr->left;
delete curr;
}
else {
if(parent->left == curr)
{
parent->left = curr->left;
delete curr;
}
else
{
parent->right = curr->left;
delete curr;
}
}
}
return;
}
//We're looking at a leaf node
if( curr->left == NULL && curr->right == NULL)
{
if (curr == root) {
root = NULL;
delete curr;
return;
}
else {
if(parent->left == curr) parent->left = NULL;
else parent->right = NULL;
delete curr;
return;
}
}
//Node with 2 children
// replace node with smallest value in right subtree
if (curr->left != NULL && curr->right != NULL)
{
tree_node* chkr;
chkr = curr->right;
if((chkr->left == NULL) && (chkr->right == NULL))
{
curr = chkr;
delete chkr;
curr->right = NULL;
}
else // right child has children
{
//if the node's right child has a left child
// Move all the way down left to locate smallest element
if((curr->right)->left != NULL)
{
tree_node* lcurr;
tree_node* lcurrp;
lcurrp = curr->right;
lcurr = (curr->right)->left;
while(lcurr->left != NULL)
{
lcurrp = lcurr;
lcurr = lcurr->left;
}
curr->data = lcurr->data;
delete lcurr;
lcurrp->left = NULL;
}
else
{
tree_node* tmp;
tmp = curr->right;
curr->data = tmp->data;
curr->right = tmp->right;
delete tmp;
}
}
return;
}
}
and the min() function
int BinarySearchTree::min()
{
tree_node *p=root;
while (p->left != NULL)
p=p->left;
return (p->data);
}
Looks like the last four lines have negated logic of the for loop.
The for loop says:
new val is larger go right else left.
The tree placement says:
new val is larger place left else place right.
Also I don't see your remove code, but the it may be affected by the wrong ordering.
Also try initializing rand before using it:
srand (time(NULL));
You need to improve on your random function. Try using int j = rand() instead.
EDIT: you have duplicate minimum values. With the code below you remove the top most node with minimum value.
while(curr != NULL)
{
if(curr->data == d)
{
found = true;
break;
}
else
{
parent = curr;
if(d>curr->data) curr = curr->right;
else curr = curr->left;
}
}
try the following code instead.
tree_node* left_most_duplicate;
while (curr != NULL)
{
if (d>curr->data) curr = curr->right;
else curr = curr->left;
if (curr->data == d)
{
parent = curr;
left_most_duplicate = curr;
found = true;
break;
}
}
curr = left_most_duplicate;