Deleting a node in a binary search tree - c++

I was implementing binary search tree and also inputting values in to the tree and traversing using inorder traversal. Every function of my class works except deletion, deletion does work at all. Moreover, I would appreciate if someone explains to me why we return values for deletion?
#include <iostream>
using namespace std;
class node {
public:
int key;
node* right;
node* left;
node(int val)
{
key = val;
right = NULL;
left = NULL;
}
};
class BinarySearchTree{
public:
node* root = NULL;
node* insert(node* root, int val) {
if (root == NULL) {
return new node(val);}
else if (val > root->key) {
root->right = insert(root->right, val);
}
else if (val < root->key) {
root->left = insert(root->left, val);
}
return root;}
void inorder(node* root) {
if (root == NULL)
return;
inorder(root->left);
cout << "our node is that " << root->key << endl;
inorder(root->right);
}
int minimumm(node* root) {
node* current = root;
while (current->left != NULL) {
current = current->left;
}
return (current->key);
}
node* deletenode(node* root, int val) {
if (root == NULL) {
return root;
}
else if (val > root->key) {
deletenode(root->right, val);
}
else if (val < root->key) {
deletenode(root->left, val);}
else {
if (root->right == NULL && root->left == NULL) {
delete(root);
return NULL;
}
else if (root->right == NULL) {
node* temp = root->left;
delete(root);
return temp;
}
else if (root->left == NULL) {
node* temp = root->right;
delete(root);
return temp;
}
else {
int temp = minimumm(root->right);
deletenode(root->right, temp);
return root;
}
}
}
};
int main() {
BinarySearchTree bst;
bst.root = bst.insert(bst.root, 100);
bst.root = bst.insert(bst.root, 19);
bst.root = bst.insert(bst.root, 47);
bst.root = bst.insert(bst.root, 3);
bst.root = bst.insert(bst.root, 111);
bst.root = bst.insert(bst.root, 78);
bst.inorder(bst.root);
bst.root = bst.deletenode(bst.root, 78);
bst.root = bst.deletenode(bst.root, 71);
bst.inorder(bst.root);
}
I tried to delete 78 and 71 using deletion class but it didn't work at all

Related

How to delete root node in BST when it has only one child?

#include <iostream>
using namespace std;
class BST {
int data;
BST *left, *right;
public:
BST();
BST(int);
BST* Insert(BST*, int);
void Delete(BST*, BST*, int);
void Inorder(BST*);
};
BST::BST():data(0), left(NULL), right(NULL) {}
BST::BST(int value):BST() {
data = value;
}
BST* BST::Insert(BST *root, int value) {
if(!root) {
return new BST(value);
}
if(value > root->data) {
root->right = Insert(root->right, value);
} else {
root->left = Insert(root->left, value);
}
return root;
}
void BST::Delete(BST *parent, BST *root, int value) {
if(!root) {
return;
}
if(root->data == value) {
if(!root->left && !root->right) {
if(parent) {
if (parent->left == root) {
parent->left = NULL;
}
else {
parent->right = NULL;
}
}
free(root);
return;
}
if(!root->left || !root->right) {
BST *child = root->left ? root->left : root->right;
if(parent) {
if (root == parent->left) {
parent->left = child;
}
else {
parent->right = child;
}
free(root);
} else {
// what do i have to do here ?
}
return;
}
BST *inorderSuccessor = root->right;
parent = root;
while (inorderSuccessor->left) {
parent = inorderSuccessor;
inorderSuccessor = inorderSuccessor->left;
}
root->data = inorderSuccessor->data;
Delete(parent, inorderSuccessor, inorderSuccessor->data);
}
if(value > root->data) {
Delete(root, root->right, value);
} else {
Delete(root, root->left, value);
}
}
void BST::Inorder(BST *root) {
if(!root) {
return;
}
Inorder(root->left);
cout << root->data << " ";
Inorder(root->right);
}
int main() {
BST bst, *root = NULL;
root = bst.Insert(root, 4);
bst.Insert(root, 2);
// bst.Insert(root, 5);
bst.Insert(root, 1);
bst.Insert(root, 3);
bst.Delete(NULL, root, 4);
bst.Inorder(root);
return 0;
}
When i do free(root) whole of tree gets deleted.
I have done almost everything I know but it just doesn't run correctly.
I am keeping track of parent node in the function itself.
I am using recursion to do that. I can tell a node is root of tree if parent is null.
Everything else is working fine. I have checked all the other cases.

problems in implementation of avl

I am trying to insert 0 through 11 into avl and then delete 4, 5, 6 in that order. I am getting sigserv error while deleting 6 in rr_rotation function. This is the first time I am implementing avl and I am new to programming. Where am I going wrong? I added a few comments for my own understanding and to track where the error has occurred. Here is my code:
#include<bits/stdc++.h>
using namespace std;
#define pow2(n) (1 << (n))
struct avl_node {
int data;
//int size;
struct avl_node *left;
struct avl_node *right;
}*root;
class avlTree {
public:
int height(avl_node *);
int diff(avl_node *);
avl_node *rr_rotation(avl_node *);
avl_node *ll_rotation(avl_node *);
avl_node *lr_rotation(avl_node *);
avl_node *rl_rotation(avl_node *);
avl_node* balance(avl_node *);
avl_node* insert(avl_node *, int);
int getBalance(avl_node*);
int getSize(avl_node*);
avl_node* minValueNode(avl_node*);
avl_node* del(avl_node *, int);
void inorder(avl_node *);
void preorder(avl_node *);
int kthsmallest(avl_node*, int);
avlTree() {
root = NULL;
}
};
int avlTree::height(avl_node *temp) {
int h = 0;
if (temp != NULL) {
int l_height = height(temp->left);
int r_height = height(temp->right);
int max_height = max(l_height, r_height);
h = max_height + 1;
}
return h;
}
int avlTree::diff(avl_node *temp) {
int l_height = height(temp->left);
int r_height = height(temp->right);
int b_factor = l_height - r_height;
return b_factor;
}
avl_node *avlTree::rr_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside rr rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->right;
if(temp == NULL)
cout<<"yes null 2"<<endl;
//cout<<"parent->right "<<temp->data<<endl;
parent->right = temp->left;
temp->left = parent;
cout<<"temp->left->data "<<temp->left->data<<endl;
return temp;
}
avl_node *avlTree::ll_rotation(avl_node *parent) {
avl_node *temp;
//cout<<"inside ll rotation"<<endl;
//cout<<"parent = "<<parent->data<<endl;
temp = parent->left;
parent->left = temp->right;
temp->right = parent;
return temp;
}
avl_node *avlTree::lr_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside lr rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->left;
parent->left = rr_rotation(temp);
return ll_rotation(parent);
}
avl_node *avlTree::rl_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside rl rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->right;
parent->right = ll_rotation(temp);
return rr_rotation(parent);
}
avl_node *avlTree::balance(avl_node *temp) {
int bal_factor = diff(temp);
if (bal_factor > 1) {
if (diff(temp->left) > 0)
temp = ll_rotation(temp);
else
temp = lr_rotation(temp);
} else if (bal_factor < -1) {
if (diff(temp->right) > 0)
temp = rl_rotation(temp);
else
temp = rr_rotation(temp);
}
return temp;
}
avl_node *avlTree::insert(avl_node *root, int value) {
//cout<<"Inside insert for val = "<<value<<endl;
if (root == NULL) {
root = new avl_node;
root->data = value;
root->left = NULL;
root->right = NULL;
return root;
} else if (value < root->data) {
root->left = insert(root->left, value);
root = balance(root);
} else if (value >= root->data) {
root->right = insert(root->right, value);
root = balance(root);
}
return root;
}
avl_node* avlTree::minValueNode(avl_node* node) {
avl_node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}
int avlTree::getBalance(avl_node* N) {
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
avl_node* avlTree::del(avl_node *root, int value) {
cout<<"del for val = "<<value<<endl;
if (root == NULL){
cout<<"root is null here\n";
return root;
}
// If the key to be deleted is smaller than the
// root's key, then it lies in left subtree
if (value < root->data)
root->left = del(root->left, value);
// If the key to be deleted is greater than the
// root's key, then it lies in right subtree
else if (value > root->data)
root->right = del(root->right, value);
// if key is same as root's key, then This is
// the node to be deleted
else {
// node with only one child or no child
if ((root->left == NULL) || (root->right == NULL)) {
avl_node* temp = root->left ? root->left : root->right;
// No child case
if (temp == NULL) {
temp = root;
root = NULL;
cout<<"Root set to null\n";
}
else{
// One child case
cout<<temp->data<<" copied to root "<<root->data<<"\n";
*root = *temp;
// Copy the contents of
// the non-empty child
}
free(temp);
} else {
// node with two children: Get the inorder
// successor (smallest in the right subtree)
avl_node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node
root->data = temp->data;
// Delete the inorder successor
root->right = del(root->right, temp->data);
}
} // If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
//root->height = 1 + max(height(root->left),height(root->right));
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to
// check whether this node became unbalanced)
int balance = getBalance(root);
cout<<"balance = "<<balance<<" for root "<<root->data<<endl;
if(root->right == NULL)
cout<<"yes null"<<endl;
// If this node becomes unbalanced, then there are 4 cases// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0){
cout<<"balance1 = "<<getBalance(root->left)<<" for root "<<root->left->data<<endl;
avl_node* t = rr_rotation(root);
//root = rr_rotation(root);
cout<<"Root of the modified sub-tree is "<<t->data<<endl;
return t;
//rr_rotation(root);
}
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0) {
cout<<"balance2 = "<<getBalance(root->left)<<" for root "<<root->left->data<<endl;
cout<<"prev root "<<root->left->data<<endl;
//root->left = ll_rotation(root->left);
root = lr_rotation(root);
cout<<"new root "<<root->data<<endl;
//return rr_rotation(root);
return root;
} // Right Right Case
if (balance < -1 && getBalance(root->right) <= 0){
cout<<"balance3 = "<<getBalance(root->right)<<" for root "<<root->right->data<<endl;
avl_node* t = rr_rotation(root);
cout<<"Root of the modified sub-tree is "<<t->data<<endl;
return t;
//return ll_rotation(root);
}
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
cout<<"balance4 = "<<getBalance(root->right)<<" for root "<<root->right->data<<endl;
//root->right = rr_rotation(root->right);
//return ll_rotation(root);
return rl_rotation(root);
}
return root;
}
void avlTree::inorder(avl_node *tree) {
if (tree == NULL)
return;
inorder(tree->left);
cout << tree->data << " ";
inorder(tree->right);
}
void avlTree::preorder(avl_node *tree) {
if (tree == NULL)
return;
cout << tree->data << " ";
preorder(tree->left);
preorder(tree->right);
}
int avlTree::getSize(avl_node* N){
if(N == NULL)
return 0;
return (getSize(N->left) + 1 + getSize(N->right));
}
int avlTree::kthsmallest(avl_node* N, int k){
int r = getSize(N->left) + 1;
if(k == r)
return N->data;
if(k < r)
return kthsmallest(N->left,k);
if(k > r)
return kthsmallest(N->right,k-r);
return -1;
}
int main(void) {
int n, i, x;
char s;
avlTree tree; for(i=0;i<12;i++){
root = tree.insert(root,i);
tree.preorder(root);
cout<<endl;
}
for(i=4;i<=6;i++){
root = tree.del(root,6);
tree.preorder(root);
cout<<endl;
}
return 0;
}

Strange value on node deletion in AVL tree

Made an AVL tree and everything worked well until I tested it with a larger amount of inserts. Upon deletion of a node with two children the data field within the node that is "moved" gets a strange value. Wich I've learned is some undefined behavior in c++. I don't have a clue on how to go about it. What am I missing?
AVL_Tree.cpp
#include "AVL_Tree.h"
#include "stddef.h"
#include <stdexcept>
#include <iostream>
#include <algorithm>
/*
* Constructor for TreeNode
*/
AVL_Tree::TreeNode::TreeNode(const int& data)
: data(data), height(1), leftChild(NULL), rightChild(NULL){};
void AVL_Tree::TreeNode::printNodeValue()
{
std::cout << data << "\n";
}
void AVL_Tree::TreeNode::printTree(bool isRight, const std::string& indent)
{
if(rightChild != NULL)
{
rightChild->printTree(true, indent + (isRight ? " " : " | "));
}
std::cout << indent;
if(isRight)
{
std::cout << " /";
}
else
{
std::cout << " \\";
}
std::cout << "----- ";
printNodeValue();
if(leftChild != NULL)
{
leftChild->printTree(false, indent + (isRight ? " | " : " "));
}
}
void AVL_Tree::TreeNode::printTree()
{
if(rightChild != NULL)
{
rightChild->printTree(true, "");
}
printNodeValue();
if(leftChild != NULL)
{
leftChild->printTree(false, "");
}
}
/*
* Constructor for the AVL_Tree
*/
AVL_Tree::AVL_Tree()
{
this->root = NULL;
this->size = 0;
}
/**
* Destructor
*/
AVL_Tree::~AVL_Tree()
{
destruct(this->root);
}
/**
* Deletes TreeNode objects recursively
*/
void AVL_Tree::destruct(TreeNode* root)
{
if(root != NULL)
{
destruct(root->rightChild);
destruct(root->leftChild);
delete root;
root = NULL;
}
}
/**
*Removes specified node
*/
void AVL_Tree::deleteNode(const int& data)
{
TreeNode* temp = remove(this->root, data);
if(temp != NULL)
{
this->root = temp;
size--;
}
}
/**
*Adds new node to the tree by calling insert()
*/
void AVL_Tree::add(const int& data)
{
try
{
TreeNode* node = new TreeNode(data);
this->root = insert(this->root, node);
size++;
}
catch(std::string s)
{
std::cout << s << std::endl;
}
}
void AVL_Tree::print()
{
root->printTree();
}
/**
* Prints the tree in ascending order
*/
void AVL_Tree::inOrder(TreeNode* current)
{
if(current != NULL)
{
inOrder(current->leftChild);
std::cout << current->data << std::endl;
inOrder(current->rightChild);
}
}
/**
*Recursively traverse the tree to find the correct place for the new node and then
*returns the tree.
*/
AVL_Tree::TreeNode* AVL_Tree::insert(TreeNode* current, TreeNode* newNode)
{
if(current == NULL)
{
return newNode;
}
if(newNode->data < current->data)
{
current->leftChild = insert(current->leftChild, newNode);
}
else if(newNode->data > current->data)
{
current->rightChild = insert(current->rightChild, newNode);
}
else
{
throw std::string("Data already exist in tree");
}
//return current;
return balance(current);
}
/**
* Recursively finds the TreeNode that matches 'dataToRemove' and erase it from the tree then returns the new tree
*/
AVL_Tree::TreeNode* AVL_Tree::remove(TreeNode* current, const int& dataToRemove)
{
if(current == NULL)
{
return current;
}
if(dataToRemove < current->data)
{
current->leftChild = remove(current->leftChild, dataToRemove);
}
else if(dataToRemove > current->data)
{
current->rightChild = remove(current->rightChild, dataToRemove);
}
else //if(dataToRemove == current->data)
{
TreeNode* temp = NULL;
//No children
if(current->leftChild == NULL && current->rightChild == NULL)
{
delete current;
current = NULL;
}
//One child
else if(current->leftChild != NULL && current->rightChild == NULL)
{
temp = current->leftChild;
current->data = temp->data;
current->leftChild = remove(current->leftChild, temp->data);
}
else if(current->leftChild == NULL && current->rightChild != NULL)
{
temp = current->rightChild;
current->data = temp->data;
current->rightChild = remove(current->rightChild, temp->data);
}
//Two children
else if(current->leftChild != NULL && current->rightChild != NULL)
{
temp = findSuccessor(current->rightChild);
current->data = temp->data;
remove(current->rightChild, temp->data);
}
}
return balance(current);
}
/**
* Returns height of tree
*/
int AVL_Tree::height(TreeNode* current)
{
if(current == NULL)
{
return 0;
}
return current->height;
}
/**
* Returns the balance factor for the argument(TreeNode pointer)
*/
int AVL_Tree::getBalance(TreeNode* current)
{
if(current == NULL)
{
return 0;
}
return height(current->rightChild) - height(current->leftChild);
}
/**
* Sets the height of the specified TreeNode
*/
void AVL_Tree::fixHeight(TreeNode* current)
{
int hl = height(current->leftChild);
int hr = height(current->rightChild);
current->height = (hl > hr ? hl : hr) + 1;
}
/**
* Takes TreeNode pointer as arguement and balances the tree if it isn't NULL
*/
AVL_Tree::TreeNode* AVL_Tree::balance(TreeNode* current)
{
if (current != NULL) {
fixHeight(current);
if(getBalance(current) == 2)
{
if(getBalance(current->rightChild) < 0)
{
current->rightChild = rotateRight(current->rightChild);
}
return rotateLeft(current);
}
if(getBalance(current) == -2)
{
if(getBalance(current->leftChild) > 0)
{
current->leftChild = rotateLeft(current->leftChild);
}
return rotateRight(current);
}
return current;
} else {
return NULL;
}
}
/**
* Preforms a left rotation
* Returns the rotated subtree
*/
AVL_Tree::TreeNode* AVL_Tree::rotateLeft(TreeNode* current)
{
TreeNode* right = current->rightChild;
current->rightChild = right->leftChild;
right->leftChild = current;
fixHeight(current);
fixHeight(right);
return right;
}
/**
* Preforms a right rotation
*/
AVL_Tree::TreeNode* AVL_Tree::rotateRight(TreeNode* current)
{
TreeNode* left = current->leftChild;
current->leftChild = left->rightChild;
left->rightChild = current;
fixHeight(current);
fixHeight(left);
return left;
}
/**
* Takes TreeNode pointer as argument and return the "leftest"(smallest) node in the right subtree.
*/
AVL_Tree::TreeNode* AVL_Tree::findSuccessor(TreeNode* current)
{
while(current->leftChild != NULL)
{
current = current->leftChild;
}
return current;
}
AVL_Tree.h
#ifndef AVLTREE_H
#define AVLTREE_H
#include <string>
class AVL_Tree
{
private:
struct TreeNode
{
TreeNode(const int& data);
int data;
int height;
TreeNode* leftChild;
TreeNode* rightChild;
void printTree(bool isRight, const std::string& indent);
void printTree();
void printNodeValue();
};
int size;
TreeNode* root;
TreeNode* findSuccessor(TreeNode* current);
TreeNode* remove(TreeNode* current, const int& dataToRemove);
TreeNode* insert(TreeNode* current, TreeNode* newNode);
int height(TreeNode* current);
TreeNode* balance(TreeNode* current);
int getBalance(TreeNode* current);
TreeNode* rotateLeft(TreeNode* current);
TreeNode* rotateRight(TreeNode* current);
void fixHeight(TreeNode* current);
void destruct(TreeNode* root);
TreeNode* findMin(TreeNode* current);
TreeNode* removeMin(TreeNode* current);
public:
AVL_Tree();
~AVL_Tree();
void deleteNode(const int& data);
void add(const int& data);
void print();
void inOrder(TreeNode* current);
};
#endif
main.cpp
#include "AVL_Tree.h"
#include <stdlib.h>
#include <vector>
using std::vector;
int main()
{
AVL_Tree at;
vector<int> list;
for(int i = 0; i < 20; i++)
{
int x = rand() % 100;
list.push_back(x);
at.add(x);
}
at.print();
at.add(list[0]);
at.print();
for(int i = 19; i >= 18; i--)
{
at.deleteNode(list[i]);
}
at.print();
return 0;
}
Output
output
If the data already exist in your tree, your code throws an exception. The calling code is assigning a pointer to a non returning function.
this->root = insert(this->root, node);
Test your code with some hard coded values and make sure to test with a duplicate value.

BST remove/delete node - root

I got a problem when I delete root node for example if I add to tree 2, 1, 3 and remove 2 (root) something goes wrong when I want to see my tree in preorder and program fails.
Could You explain what's going wrong?
#include <iostream>
#include <string>
using namespace std;
struct BST {
int data;
BST* left;
BST* right;
};
BST* GetNewNode (int data)
{
BST* newNode = new BST ();
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
//******************************BST******************************************************
BST * insertBST (BST * root, int data);
BST * search (BST* root , int data);
BST* FindMin(BST* root);
BST* Delete (BST* root, int data);
BST* DeleteAll(BST* root);
void Inorder(BST *root);
void Preorder(BST *root);
void Postorder(BST *root);
//****************************MAIN***********************************
int main()
{
BST* root = NULL;
string menu= " ";
int f ;
while(menu!="k")
{
cout<<"Chose function (i, r, in ,pre, post, del, f)"<<endl
<<"Want to quit tap k"<<endl;
cin>>menu;
if(menu== "i" )
{
cout<<"If you want to end inserting write 0"<<endl;
cin>>f;
while(f)
{
root = insertBST (root,f );
cin>>f;
}
}
else if(menu == "r" )
{
cout<<"Insert data of node to delete"<<endl;
cin>>f;
Delete(root , f);
}
else if(menu == "in")
Inorder (root);
else if(menu == "pre")
Preorder (root);
else if(menu == "post")
Postorder (root);
else if(menu == "del")
root = DeleteAll(root);
else if(menu == "find")
{
cin>> f;
search(root , f);
}
}
DeleteAll (root);
return 0;
}
///---------------------------------------
BST* insertBST (BST* root, int data)
{
if (root == NULL)
{
root = GetNewNode (data);
}
else if (data <= root->data)
{
root->left = insertBST (root->left, data);
}
else
{
root->right = insertBST (root->right, data);
}
return root;
}
BST* search (BST* root , int data)
{
if (root == NULL) {cout <<"Not found "<<endl; return NULL;}
else if (root->data == data){ cout<<"Found "<<root->data <<endl ;return root;}
else if (data<= root->data) return search (root->left, data);
else return search (root->right, data);
}
BST* Delete (BST* root, int data)
{
if(root == NULL) return root;
else if(data < root->data) root->left = Delete(root->left,data);
else if(data > root->data) root->right = Delete(root->right, data);
else
{
if(root->left == NULL && root->right == NULL)
{
delete root;
root = NULL;
} else if(root->left == NULL)
{
struct BST *temp = root;
root = root->right;
delete temp;
} else if(root->right == NULL)
{
struct BST *temp = root;
root = root->left;
delete temp;
} else{
struct BST *temp = FindMin(root->right);
root->data = temp->data;
root->right = Delete(root->right, temp->data);
}
}
return root;
}
void Inorder(BST *root)
{
if(root == NULL) return;
Inorder(root->left);
cout<<root->data<<" ";
Inorder(root->right);
}
void Preorder(BST *root)
{
if (root != NULL)
{
cout<< root->data<<" ";
Preorder (root->left);
Preorder (root->right);
}
else if (root == NULL)
return;
}
void Postorder(BST *root)
{
if (root == NULL)
return;
Postorder (root->left);
Postorder (root->right);
cout<< root->data<<" ";
}
BST* FindMin(BST* root)
{
while(root->left != NULL) root = root->left;
return root;
}
BST* DeleteAll(BST* root)
{
if (root!=NULL)
{
DeleteAll(root->left);
DeleteAll(root->right);
delete(root);
root = NULL;
}
return root;
}
What you are doing is called inorder. below you can check preorder
Preorder:
do stuff with the node // pre means before
recurse left
recurse right
void Preorder(BST *root)
{
if (root == NULL)
return;
cout<< root->data<<" ";
Preorder (root->left);
Preorder (root->right);
}

AVL Tree Compiles and Runs But Crashes Instantly

So the program I have here will compile however it will crash instantly if I create a class object. What I mean is, in my main.cpp if I create say "AVLTree obj;" The program crashes....
If I leave that out then everything is fine... Any help would be appreciated.
Thank You. // MAIN below
using namespace std;
int main()
{
cout << "******************************" << endl;
cout << " Self Balancing AVL Tree " << endl;
cout << "******************************" << endl;
/** AVLtree obj;
obj.insert(100);
obj.insert(20);
obj.insert(25);
obj.insert(200);
assert isEmpty();
obj.preOrderPrint(*root);
obj.inOrderPint(*root);
obj.postOrderPrint(*root);
obj.remove(20);
*/
return 0;
}
HEADER
#ifndef AVLTREE_H
#define AVLTREE_H
//Moved this outside of the class trying to get things running
struct TreeNode
{
int key;
int data;
TreeNode *parent;
TreeNode *right;
TreeNode *left;
char factor; //byte
};
//-------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------- s
class AVLtree
{
private:
protected:
//neccessary tree nodes
TreeNode *root;
TreeNode *tmp, *node;
TreeNode *holder1, *holder2, *holder3, *newnode;
int tmpdata;
bool h;
int height(TreeNode * pos) const;
int max(int a, int b) const;
//Rotate functions broken up individually and used within the
//insert function. Was having pointer issues when insert was
//all one function
TreeNode * singleRotateLeft(TreeNode *holder2);
TreeNode * singleRotateRight(TreeNode *holder2);
TreeNode * doubleRotateLeft(TreeNode *holder2);
TreeNode * doubleRotateRight(TreeNode *holder2);
TreeNode * _insert(int key, TreeNode * node);
TreeNode * _remove(int key, TreeNode * node);
public:
AVLtree();
void insert(int key, int data);
bool isEmpty();
void remove(int key);
int retrieve(int key);
void preOrderPrint(TreeNode *root)const;
void inOrderPrint(TreeNode *root)const;
void postOrderPrint(TreeNode *root)const;
int size;
};
#endif // AVLTREE_H
CPP for HEADER
#include "avltree.h"
#include <cstdio>
#include <iostream>
using namespace std;
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
AVLtree::AVLtree()
{
size = 0;
//Initialize values
root = NULL;
root->left = NULL;
root->right = NULL;
root->parent = NULL;
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
int AVLtree::retrieve(int key)
{
//height of 0 means the tree must be empty
if(size == 0)
{
return NULL;
}
tmp = root;
//While not empty search both sides of tree for key
while(tmp != NULL)
{
if(key < tmp->key)
tmp = tmp->left;
else if(key > tmp->key)
tmp = tmp->right;
else
return tmp->data;
}
return NULL;
}
//Simple bool determining if the tree is empty via the root
bool AVLtree::isEmpty()
{
if(root == NULL)
{
cout << "The Tree Is Empty!! " << endl;
return true;
}
else
{
cout << "The Tree Is NOT Empty" << endl;
return false;
}
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
int AVLtree::height( TreeNode * pos ) const
{
if( pos == NULL )
return -1;
else
return pos->factor;
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
int AVLtree::max( int a, int b ) const
{
return a > b ? a : b;
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
TreeNode * AVLtree::singleRotateLeft(TreeNode *holder2)
{
holder1 = holder2->left;
holder2->left = holder1->right;
holder1->right = holder2;
holder2->factor = max(height(holder2->left), height(holder2->right))+1;
holder1->factor = max(height(holder1->left), holder2->factor)+1;
return holder1; // new root
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
TreeNode * AVLtree::singleRotateRight(TreeNode *holder1)
{
holder2 = holder1->right;
holder1->right = holder2->left;
holder2->left = holder1;
holder1->factor = max(height(holder1->left), height(holder1->right))+1;
holder2->factor = max(height(holder2->right), holder1->factor)+1;
return holder2; // new root
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
TreeNode * AVLtree::doubleRotateLeft(TreeNode *holder3)
{
holder3->left = singleRotateRight(holder3->left);
return singleRotateLeft(holder3);
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
TreeNode * AVLtree::doubleRotateRight(TreeNode *holder1)
{
holder1->right = singleRotateLeft(holder1->right);
return singleRotateRight(holder1);
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
void AVLtree::insert(int key, int data)
{
size++;
tmpdata = data;
root =_insert(key,root);
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
TreeNode * AVLtree::_insert(int key, TreeNode * node)
{
//Empty case, create a new tree
if (node == NULL)
{
node = new TreeNode;
node->factor = 0;
node->key = key;
node->data = tmpdata;
node->left = NULL;
node->right = NULL;
// if(size==1)
// root=node;
}
//Key is less than, move down the left child
else if(key < node->key)
{
node->left= _insert(key,node->left);
if(height(node->left) - height(node->right) == 2)
{
if(key < node->left->key)
node = singleRotateLeft(node);
else
node = doubleRotateLeft(node);
}
}
//Key is greater than move down the right child
else if(key > node->key)
{
node->right= _insert(key,node->right);
if(height(node->right) - height(node->left) == 2)
{
if(key > node->right->key)
node = singleRotateRight(node);
else
node = doubleRotateRight(node);
}
}
// node->factor=-1;
// if(node->left!=NULL)
// node->factor=node->left->factor;
// if(node->right!=NULL)
// node->factor=max(node->factor, node->right->factor);
node->factor = max(height(node->left ),height(node->right))+1;
return node;
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
void AVLtree::preOrderPrint(TreeNode *node) const
{
//Empty node returns out
if(node == NULL) return;
//print the contents of the node specified
cout << node->data << " ";
//Navigate and display left subtree
preOrderPrint(node->left);
//Followed by the right subtree
preOrderPrint(node->right);
}
void AVLtree::inOrderPrint(TreeNode *node) const
{
if(node == NULL) return;
inOrderPrint(node->left);
// Root middle value is displayed in the middle of the printing
//operation
cout << node->data << " ";
inOrderPrint(node->right); // Left childeren last to be printed
}
void AVLtree::postOrderPrint(TreeNode *node) const
{
if(node == NULL) return; // Empty tree returns
postOrderPrint(node->left); //Display left side subtree
postOrderPrint(node->right); // Followed by right side subtree
cout << node->data << " "; //Finish with root
}
void AVLtree::remove(int key)
{
root =_remove(key,root);
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
TreeNode * AVLtree::_remove(int key, TreeNode * node)
{
//temp bool determining state of removal
bool done = false;
//Empty case there is nothing to do, return done immediately
if (node == NULL)
{
h = false;
done = true;
}
else
//If key data is less than the current node
if (key < node->key) //delete from left subtree
{
newnode =_remove(key,node->left);
node->left = newnode;
if(h)
{
//Check for height imbalance
if(height(node->right) - height(node->left) == 2)
{
if(height(node->right) > height(node->left))
node = singleRotateLeft(node);
else
node = singleRotateRight(node);
}
node->factor = max(height(node->left ),height(node->right))+1;
if (node->factor >= 0)
{
node->factor = root->factor -1;
if (node->factor == -1)
h = false;
}
else if (node->right->factor == -1)
singleRotateRight(node);
else
singleRotateLeft(node);
done = true;
return node;
}
}
else if (key == node->key) //del node
{
if (node->left == NULL || node->right == NULL) // one or no children
{
if (node->left == NULL)
holder1 = node->right;
else
holder1 = node->left;
delete node;
h = true; done = true;
return(holder1);
}
else // both of children
{
holder2 = node->right;
while (holder2->left != NULL)
holder2 = holder2->left;
node->key = holder2->key;
key = node->key;
}
}
if (!done && key >= node->key) // delete from right subtree
{
newnode=_remove(key, node->right);
node->right = newnode;
if (h)
{
if(height(node->right) - height(node->left) == 2)
{
if(height(node->right) > height(node->left))
node = singleRotateLeft(node);
else
node = singleRotateRight(node);
}
node->factor = max(height(node->left ),height(node->right))+1;
//
/* if (node->factor <= 0)
{
node->factor=node->factor+1;
if (node->factor ==1)
h=false;
}
else if (node->right->factor==1)
singleRotateLeft(node);
else
singleRotateRight(node);*/
return node;
}
}
}
//-------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------
You don't think this code is a problem?
root = NULL;
root->left = NULL;
root->right = NULL;
root->parent = NULL;
Specifically, you're initializing your root node to null, then trying to assign values to root's properties. You can't dereference / assign values to a null pointer.