So I've been working on this self-balancing AVL tree, and I feel like its working correctly, but there are some memory leaks. I've search and gone through a million times it feels like trying to figure out what I'm doing wrong but I'm new to this whole memory leak thing and obviously need to learn more. If anyone can help me out or can see where the leaks may be that would be awesome, here is the code for my AVL tree:
#pragma once
#include <algorithm>
#include <fstream>
#include "LinkedList.h"
template <typename ItemType>
class AVLTreeSet {
private:
struct Node {
ItemType info;
Node* left;
Node* right;
int height;
};
Node* root;
int size;
public:
AVLTreeSet()
{
root = NULL;
size = 0;
}
~AVLTreeSet()
{
clear();
}
void clear()
{
Node* n = root;
if(n != NULL)
{
clearTree(n->left);
clearTree(n->right);
delete n;
}
root = NULL;
}
void clearTree(Node* n)
{
if(n != NULL)
{
clearTree(n->left);
clearTree(n->right);
delete n;
}
}
void print(std::ofstream &out)
{
//cout << "HERE" << endl;
LinkedList<Node*> list;
int level = 0;
int levelSize;
int count = 0;
Node* n = root;
if (n == NULL)
{
return;
}
list.insert(n);
levelSize = list.getSize();
while(list.getSize() != 0)
{
count = 0;
out << "level " << level << ": ";
for (unsigned i = levelSize; i > 0; i--)
{
count++;
if (count > 8)
{
out << std::endl;
out << "level " << level << ": ";
count = 0;
}
n = list.getInfo();
out <<n->info << "(" << getHeight(n) << ") ";
if (n->left != NULL)
{
//cout << "left is not null" << endl;
list.insert(n->left);
}
if (n->right != NULL)
{
list.insert(n->right);
//cout << "right is not null" << endl;
}
list.remove();
}
levelSize = list.getSize();
level++;
out << std::endl;
//levelSize = list.getSize();
}
}
void insert(const ItemType& item)
{
//cout << "Insert FUNCTION" << endl;
Node* current = root;
if (current == NULL)
{
//cout << "ADD FUNCTION NULL" << endl;
current = new Node;
current->info = item;
current->left = NULL;
current->right = NULL;
current->height = 0;
root = current;
size++;
//cout << current->info << endl;
//cout << current->height << endl;
return;
}
if (current->info > item)
{
current->left = add(item, current->left);
}
if (current->info < item)
{
current->right = add(item, current->right);
}
current = balance(current);
root = current;
}
Node* add(const ItemType& item, Node* current)
{
if (current == NULL)
{
current = new Node;
current->info = item;
current->left = NULL;
current->right = NULL;
current->height = 0;
size++;
}
if (current->info > item)
{
current->left = add(item, current->left);
}
if (current->info < item)
{
current->right = add(item, current->right);
}
return current;
}
void remove(const ItemType& item)
{
Node* current = root;
if (current == NULL)
{
//cout << "NULL" << endl;
return;
}
if (current->info == item)
{
//cout << "FOUND" << endl;
current = removeNext(item, current);
current = balance(current);
root = current;
return;
}
if (current->info > item)
{
//cout << "LEFT" << endl;
current->left = removeNext(item, current->left);
if (current == root)
{
root = balance(current);
}
return;
}
if (current->info < item)
{
//cout << "RIGHT" << endl;
current->right = removeNext(item, current->right);
if (current == root)
{
root = balance(current);
}
return;
}
}
Node* removeNext(const ItemType& item, Node* current)
{
Node* temp;
if (current != NULL)
{
if (current->info > item)
{
//cout << "REMOVENEXT LEFT" << endl;
current->left = removeNext(item, current->left);
return current;
}
if (current->info < item)
{
//cout << "REMOVENEXT RIGHT" << endl;
current->right = removeNext(item, current->right);
return current;
}
//cout << "FOUND" << endl;
if (current->left != NULL && current->right != NULL)
{
//cout << "LEFT AND RIGHT CHILDREN" << endl;
temp = current;
current = CTR(current->right);
current->left = temp->left;
//cout << current->info << endl;
//looker = removeNext(current->info, temp->right);
delete temp;
size--;
current = balance(current);
return current;
}
else if (current->right != NULL)
{
//cout << "RIGHT ONE CHILD" << endl;
temp = current;
current = current->right;
delete temp;
size--;
current = balance(current);
return current;
}
else if (current->left != NULL)
{
//cout << "LEFT ONE CHILD" << endl;
temp = current;
current = current->left;
delete temp;
size--;
current = balance(current);
return current;
}
//cout << "CURRENT NODE" << endl;
delete current;
size--;
return NULL;
}
//cout << "NOT FOUND" << endl;
return current;
}
Node* CTR(Node* current)
{
while(current->left != NULL)
{
//cout << "ENTERED LOOP" << endl;
current = current->left;
}
//cout << current->info << endl;
return current;
}
bool find(const ItemType& item)
{
Node* current = root;
bool find = false;
if (current == NULL)
{
return find;
}
if (item == current->info)
{
find = true;
return find;
}
if (current->info > item && current->left != NULL)
{
find = findLeft(item, current->left);
}
if (current->info < item && current->right != NULL)
{
find = findRight(item, current->right);
}
return find;
}
bool findLeft(const ItemType& item, Node* current)
{
bool find = false;
if (item == current->info)
{
find = true;
return find;
}
if (current->info > item && current->left != NULL)
{
find = findLeft(item, current->left);
}
if (current->info < item && current->right != NULL)
{
find = findRight(item, current->right);
}
return find;
}
bool findRight(const ItemType& item, Node* current)
{
bool find = false;
if (item == current->info)
{
find = true;
return find;
}
if (current->info > item && current->left != NULL)
{
find = findLeft(item, current->left);
}
if (current->info < item && current->right != NULL)
{
find = findRight(item, current->right);
}
return find;
}
int getHeight(Node* temp)
{
int h = 0;
if (temp != NULL)
{
int l_height = getHeight(temp->left);
int r_height = getHeight(temp->right);
int max_height = std::max(l_height, r_height);
h = max_height + 1;
}
return h;
}
void setHeight(Node* n)
{
n->height = std::max(getHeight(n->right), getHeight(n->left)) + 1;
}
Node* balance(Node* n)
{
if (size == 1)
{
return n;
}
else if(getHeight(n->left) - getHeight(n->right) > 1) //n is out of balance
{
//cout << "BALANCE RIGHT" << endl;
n = balanceToRight(n);
}
else if(getHeight(n->right) - getHeight(n->left) > 1)
{
//cout << "BALANCE LEFT" << endl;
n = balanceToLeft(n);
}
return n;
}
Node* balanceToRight(Node* n)
{
if(getHeight(n->left->right) > getHeight(n->left->left))
{
n->left = rotateLeft(n->left); //<--- extra step for double rotate
}
n = rotateRight(n); //<--- this is for single
return n;
}
Node* balanceToLeft(Node* n)
{
if(getHeight(n->right->left) > getHeight(n->right->right))
{
n->right = rotateRight(n->right); //<--- extra step for double rotate
}
n = rotateLeft(n); //<--- this is for single
return n;
}
Node* rotateRight(Node* n)
{
Node* temp = n->left;
n->left = temp->right;
temp->right = n;
setHeight(n); //<--- set first
setHeight(temp);
return temp;
}
Node* rotateLeft(Node* n)
{
Node* temp = n->right;
n->right = temp->left;
temp->left = n;
setHeight(n); //<--- set first
setHeight(temp);
return temp;
}
};
I run the program by reading in a file with my main.cpp that calls the commands of my AVLtree. I know its a lot of code but I'm stressing out because I can't find where it maybe happening. Thanks.
How do you know that there are memory leak(s)?
Unless you use some tool to find the memory leak, for example valgrind as suggested by #jsantander, then try the following:
Avoid code duplication. There is too much of duplication in the present form. For example clear() could be simplified by just calling cleartree(root). Similar for insert().
Print/log memory each memory allocation (new) and deallocation (delete)
Keep always increasing counters, newCount and deleteCount. At the end of significant methods, add an assertion, assert( newCount - deleteCount == size );. At the first occurrence of memory leak, the assert() would blow. See http://accu.org/var/uploads/journals/overload102.pdf, page 7, "Other experiences"
Related
I am working on reverse linked list on Windows 10 Pro (64 bit) with Visual Studio Community 2019. I would like to know how to resolve the error I get as below. I get below error in the while loop in the member function reverse() in the class List
(*Please assume the list is already prepared like contiguous integer e.g. 0,1,2,3,4,5)
Could you please anyone give me some advice? Thank you in advance.
Unhandled exception thrown: read access violation.
current was 0xDDDDDDDD.
#include <iostream>
#include <string.h>
#include <vector>
using std::cout;
using std::endl;
template <class Data>
class Node
{
public:
Node* next;
Data data;
};
template <class Data>
class List
{
private:
Node<Data>* head;
Node<Data>* tail;
int count;
public:
//constructor
List()
{
count = 0;
head = nullptr;
tail = nullptr;
}
int size()
{
return count;
}
void msg_empty_list()
{
cout << "The list is not modified since it is empty." << endl;
}
int push_back(Data data)
{
Node<Data>* node = new Node<Data>;
node->data = data;
node->next = nullptr;
if (head == nullptr)
{
head = node;
tail = node;
}
else if (head != nullptr)
{
tail->next = node;
tail = tail->next;
}
count++;
return count;
}
int push_front(Data data)
{
Node<Data>* node = new Node<Data>;
node->data = data;
node->next = nullptr;
if (head == nullptr)
head = node;
else if (head != nullptr)
{
node->next = head;
head = node;
}
count++;
return count;
}
int pop_front(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
Node<Data>* temp;
temp = head;
head = head->next;
delete temp;
count--;
return count;
}
}
int pop_back(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
Node<Data>* temp = head;
while (temp->next != tail)
temp = temp->next;
delete tail;
tail = temp;
count--;
return count;
}
}
int remove_at(int index)
{
if (head == nullptr)
return -1;
else if (head != nullptr)
{
cout << "Specified index = " << index << endl;
if (index == 0)
{
pop_front();
}
else if (index == -1)
{
pop_back();
}
Node<Data>* temp = head;
Node<Data>* rmv;
int countIndex = 0;
while (countIndex < index - 1)
{
temp = temp->next;
countIndex++;
}
rmv = temp->next;
temp->next = temp->next->next;
delete rmv;
count--;
return count;
}
}
void reverse()
{
Node<Data>* temp = nullptr;
Node<Data>* prev = nullptr;
Node<Data>* current = head;
while (current != nullptr)
{
temp = current->next; // where I get error "Unhandled exception thrown: read access violation. **current** was 0xDDDDDDDD."
current->next = prev;
prev = current;
current = temp;
}
head = prev;
}
void print()
{
Node<Data>* temp = head;
if (head == nullptr)
return;
for (int i = 0; i < count - 1; i++)
{
cout << temp->data << ", ";
temp = temp->next;
}
cout << temp->data;
}
~List()
{
Node<Data>* temp = head;
while (temp->next != nullptr)
{
temp = temp->next;
delete head;
head = temp;
}
}
};
int main()
{
Node<int> x;
Node<bool> y;
Node<char> n;
List<int> list;
//insert items into list
for (int i = 0; i < 10; i++)
{
list.push_back(i);
}
cout << "Original list[size=" << list.size() << "]: ";
//print the list
list.print();
cout << endl;
// push a node to the beginning of the list
cout << endl << "==> Push a node to the head" << endl;
list.push_front(-1);
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
// pop the head of the list
cout << endl << "==> Pop a node from the head" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.pop_front();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
/*
// pop the tail of the list
cout << endl << "==> Pop a node from the tail" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.pop_back();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
*/
// delete the node at the specified index
cout << endl << "==> Delete the node at the specified index" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.remove_at(5);
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
// reverse the list
cout << endl << "==> Reverse the list" << endl;
if (list.size() == 0)
list.msg_empty_list();
else
{
list.reverse();
cout << "Modified list[size=" << list.size() << "]: ";
list.print();
cout << endl;
}
return 0;
}
I can spot a few mistakes in your code, but let's concentrate on the pop_back() function:
int pop_back(void)
{
if (head == nullptr)
return -1;
else if (head != nullptr) // 1)
{
Node<Data>* temp = head;
while (temp->next != tail) // 2)
temp = temp->next;
delete tail;
tail = temp; // 3)
count--;
return count;
}
}
Please don't do this: if (a == nullptr) {...} else if (a != nullptr) {...} is redundant. Just leave the second if away. It lets a reader believe there could be a third case.
It may be luck that this usually works, but some of the other methods don't properly update the tail pointer, so this might never be true. Validate your pop_front method when there's only one element in the list. Other functions might have similar problems.
Here's the actual problem you're observing. You're not setting the next pointer of the new tail element to null, instead it points to the now deleted tail. Insert tail->next = nullptr after this line.
Consider the following AVL-tree implementation. Each node contains a list of numbers.The key is named workload, but consider it as a plain double variable. If a key is equal to the key of an already existing node, the number gets pushed into the list. Every time I pop a number from a list, I perform a check, if the node's list is empty -> remove the node. But, after the element with key=3 gets removed completely, the list of the node with key=4 is suddenly empty. I've been trying to solve it for over 10 hours now, it's actually the first time I ever needed to ask something here. Pardon me if I miss a few things.
#include<iostream>
#include <list>
using namespace std;
class BST
{
struct node
{
double workload;
list<int> numbers;
node* left;
node* right;
int height;
};
node* root;
unsigned long long size;
bool empty;
void makeEmpty(node* t)
{
if(t == NULL)
return;
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
node* insert(double workload,int number, node* t)
{
if(t == NULL)
{
t = new node;
t->workload = workload;
t->numbers.push_back(number);
t->height = 0;
t->left = t->right = NULL;
}
else if(t->workload == workload){
t->numbers.push_back(number);
}
else if(workload < t->workload)
{
t->left = insert(workload, number, t->left);
if(height(t->left) - height(t->right) == 2)
{
if(workload < t->left->workload)
t = singleRightRotate(t);
else
t = doubleRightRotate(t);
}
}
else if(workload > t->workload)
{
t->right = insert(workload, number, t->right);
if(height(t->right) - height(t->left) == 2)
{
if(workload > t->right->workload)
t = singleLeftRotate(t);
else
t = doubleLeftRotate(t);
}
}
//if x == t->workload instead of using int workload. its a list and we push into it.
t->height = max(height(t->left), height(t->right))+1;
return t;
}
node* singleRightRotate(node* &t)
{
node* u = t->left;
t->left = u->right;
u->right = t;
t->height = max(height(t->left), height(t->right))+1;
u->height = max(height(u->left), t->height)+1;
return u;
}
node* singleLeftRotate(node* &t)
{
node* u = t->right;
t->right = u->left;
u->left = t;
t->height = max(height(t->left), height(t->right))+1;
u->height = max(height(t->right), t->height)+1 ;
return u;
}
node* doubleLeftRotate(node* &t)
{
t->right = singleRightRotate(t->right);
return singleLeftRotate(t);
}
node* doubleRightRotate(node* &t)
{
t->left = singleLeftRotate(t->left);
return singleRightRotate(t);
}
node* findMin(node* t)
{
if(t == NULL)
return NULL;
else if(t->left == NULL)
return t;
else
return findMin(t->left);
}
node* findMax(node* t)
{
if(t == NULL)
return NULL;
else if(t->right == NULL)
return t;
else
return findMax(t->right);
}
node* find(node* t,double workload){
if (t->workload == workload){
return t;
}
else if(workload < t->workload && t->left!=NULL)
return find(t->left,workload);
else if(workload > t->workload && t->right!=NULL)
return find(t->right,workload);
else{
cout << "Null node encountered" << endl;
return t;
}
}
node* remove(double x, node* t)
{
node* temp;
// Element not found
if(t == NULL)
return NULL;
// Searching for element
if(x < t->workload)
t->left = remove(x, t->left);
else if(x > t->workload)
t->right = remove(x, t->right);
// Element found
// With 2 children
else if(t->left && t->right)
{
temp = findMin(t->right);
t->workload = temp->workload;
t->right = remove(t->workload, t->right);
}
// With one or zero child
else
{
temp = t;
if(t->left == NULL)
t = t->right;
else if(t->right == NULL)
t = t->left;
delete temp;
}
if(t == NULL)
return t;
t->height = max(height(t->left), height(t->right))+1;
// If node is unbalanced
// If left node is deleted, right case
if(height(t->left) - height(t->right) == -2)
{
// right right case
if(height(t->right->right) - height(t->right->left) == 1)
return singleLeftRotate(t);
// right left case
else
return doubleLeftRotate(t);
}
// If right node is deleted, left case
else if(height(t->right) - height(t->left) == 2)
{
// left left case
if(height(t->left->left) - height(t->left->right) == 1){
return singleRightRotate(t);
}
// left right case
else
return doubleRightRotate(t);
}
return t;
}
int height(node* t)
{
return (t == NULL ? -1 : t->height);
}
int getBalance(node* t)
{
if(t == NULL)
return 0;
else
return height(t->left) - height(t->right);
}
void inorder(node* t)
{
if(t == NULL)
return;
inorder(t->left);
cout << t->workload<< " ";
inorder(t->right);
}
//Reverse inorder (Sorted highest to lowest)
void rinorder(node* t)
{
if(t == NULL)
return;
rinorder(t->right);
cout << t->workload << " ";
rinorder(t->left);
}
void preorder(node* t)
{
if (t == NULL)
return;
cout << t->workload << " ";
preorder(t->left);
preorder(t->right);
}
void postorder(node* t)
{
if (t == NULL)
return;
postorder(t->left);
postorder(t->right);
cout << t->workload << " ";
}
public:
BST()
{
root = NULL;
}
void insert(double workload, int number)
{
root = insert(workload, number, root);
}
void remove(double workload)
{
root = remove(workload, root);
}
void displayrin()
{
cout << "Rinorder: ";
rinorder(root);
cout << endl;
}
void displayin()
{
cout << "Inorder: ";
inorder(root);
cout << endl;
}
void displaypost()
{
cout << "Postorder: ";
postorder(root);
cout << endl;
}
void displaypre()
{
cout << "Preorder: ";
preorder(root);
cout << endl;
}
double getMax(){
return findMax(root)->workload;
}
int getMaxNum(){
return find(root,getMax())->numbers.front();
}
int getNum(double workload){
return find(root,workload)->numbers.front();
}
//We pop a Num from a node
void popnumber(double workload){
node *t = find(root,workload);
if(t!=NULL){
if(!t->numbers.empty()){
t->numbers.pop_front();
//If the Num list of the node is empty, remove node
if(t->numbers.empty()){
remove(t->workload);
}
}
}
}
};
int main()
{
BST t;
//key value pairs
t.insert(2,1);
t.insert(3,1);
t.insert(3,2);
t.insert(4,7);
cout << t.getNum(4) << endl;
cout << t.getNum(3)<<endl;
t.popnumber(3);
cout << t.getNum(3)<<endl;
t.popnumber(3);
t.displayin();
t.displaypost();
t.displaypre();
t.displayrin();
cout << t.getNum(4) << endl;
cout << "The max is : " << t.getMax() << endl;
cout << "The top Num of the Max is : " << t.getMaxNum() << endl;
return 0;
}
As mentioned in the comments, the problem is in the "Element found With 2 children" section of remove.
To remove the element, you find the next element in the tree. Your implementation then wants to copy the contents of the found node (temp). You copy the workload value, so that both t and temp have the same workload value (4). You do not copy the numbers list. The t node has a workload of 4 and an empty numbers list, while temp has a workload of 4 and a numbers list consisting of one element, 7. You then delete temp, losing the list.
One fix would be to copy (or move) numbers from temp to t before removing it from the tree. Adding a MoveData method to node that would move the data fields (while not altering the tree specific fields) would make it easier to add new data fields.
Another fix would be to change how you're doing the data update. If you update all pointers (and other tree related fields like height), then you don't have to worry about the data (and any pointers/iterators to the nodes would not be invalidated).
I'm not how to debug this one function of my code, When I remove and output my linked list it gives me a funky decimal. Any help would be appreciated.
void list_tail_remove(node*& head_ptr)
{
if (head_ptr == NULL)
{
cout << "Error:The Double linked List was never Created" << endl;
}
else
{
node* current = head_ptr;
while (current->link() != NULL)
{
current = current->link();
}
node* temp;
for (temp = head_ptr; temp != current; temp = temp->link())
{
temp = temp->link();
}
temp->set_link(NULL);
delete temp;
}
}
the following code is for removing a node of a binary tree. I have stepped through the code and I'm pretty sure the problem lies in the last "else if" in destroy(). I'm trying to replace a given node with a smallest node then delete that given node. remove() and findsmallest work like they should I think. when I reprint the tree its like no changes have been made.I'm obviously a beginner, so any hints/help will be much appreciated!
void remove(Key k)
{
remove(k, root);
}
void remove(Key k, BinarySearchTreeNode<Key, Value> * n)
{
if (n)
{
if (root->key == k)
removeRoot();
else
{
//1 child
if ( (n->left != nullptr) && (k < n->key) )
{
if (k == n->left->key)
destroy(n->left, true);
else
remove(k, n->left);
}
else if (n->right && k > n->key )
{
if (k == n->right->key)
destroy(n->right, false);
else
remove(k, n->right);
}
else
{
cout << "no remove\n";
}
}
}
else
cout << "trww is empty";
}
void destroy(BinarySearchTreeNode<Key, Value> * n, bool isLeft)
{
if (n == nullptr)
{
return;
}
else if (!n->left && !n->right)
{
n->left = nullptr;
n->right = nullptr;
n->parent = nullptr;
delete n;
n = nullptr;
}
else if (!n->left && n->right)
{
isLeft ? n->parent->left = n->right : n->parent->right = n->right;
cout << "killing " << n->key << endl;
n->parent = nullptr;
n->left = nullptr;
n->right = nullptr;
delete n;
n = nullptr;
}
else if (n->left && !n->right)
{
isLeft ? n->parent->left = n->left : n->parent->right = n->left;
cout << "killing " << n->key << endl;
n->parent = nullptr;
n->left = nullptr;
n->right = nullptr;
delete n;
n = nullptr;
}
/* The program goes to the code below*/
else if (n->left && n->right)
{
BinarySearchTreeNode<Key, Value> * small = findSmallest(n->right);
if (isLeft)
n->parent->left = small;
else
n->parent->right = small;
small->parent = n->parent;
small->left = n->left;
small->right = n->right;
n->parent = nullptr;
n->left = nullptr;
n->right = nullptr;
//Key smallKey = small->key;
//Value smallValue = small->value;
cout << "killing " << n->key << endl;
delete n;
n = nullptr;
}
else
cout << "fail";
}
BinarySearchTreeNode<Key, Value> * findSmallest(BinarySearchTreeNode<Key, Value> * n)
{
if (!n)
return part;
else
{
if (n->left)
return findSmallest(n->left);
else
return n;
}
}
You give the node to destroy() as a pointer. This means you can do all the things you did, except change the variable in to calling method.
When you say n= nullptr; in destroy() it only changes the local variable. It doesn't change the calling variable, for example n->right to nullptr so it will still point to the place where the deleted object was.
If you set the parameter to be a reference to a pointer (*&) you can change the calling variable and actually remove the pointer to the node.
The reason why it looks like the original tree is because the memory allocated to the deleted node happened not to be reused yet. Later it would be and your tree would cause access to a wrong pointer and maybe crash. The behaviour is undefined.
A partner of mine and I are working on an assignment for a class of ours and we have ran into a problem with one our cpp files. The purpose of the assignment is to use a generic binary search tree to implement a student/faculty database. A problem we have run into is that when we try to compile we run into an error on our delete function for the binary search tree. It's telling me that the TreeNode struct I have to create my nodes is an undefined type. However, for the other methods we get no errors. It's specifically for the delete method. Here's some the code of the cpp file with the methods of the BST:
#include <iostream>
#include <cstdlib>
#include "BinarySearchTree.h"
using namespace std;
//template <class T> BST<T>::BST():root(NULL){}
template <class T>
void BST<T>::freeMemory(BST::TreeNode *node)
{
if(node == nullptr)
return;
freeMemory(node->left);
freeMemory(node->right);
delete node;
}
template <class T>
void BST<T>::insert(T value)
{
TreeNode *treeNode = NULL;
/*try
{
}
catch()
*/
TreeNode *temp = NULL;
TreeNode *prev = NULL;
temp = root;
while(temp)
{
prev = temp;
if(temp->data < treeNode->data)
temp = temp->right;
else
temp = temp->left;
}
if(prev == NULL)
root = treeNode;
else
{
if(prev->data < treeNode->data)
prev->right = treeNode;
else
prev->left = treeNode;
}
}
template<class T>
void BST<T>::print(TreeNode *root)
{
if(root == NULL)
return;
print(root->left);
cout << root->data << endl;
print(root->right);
}
template<class T>
void BST<T>:: print()
{
print(root);
}
template<class T>
void BST<t>:: deleteNode(TreeNode *n, T item)
{
bool found = false;
TreeNode *prev = nullptr;
TreeNode *current = n;
if(current == nullptr)
cout<<"There is nothing in your tree."<< endl;
return;
while(current != nullptr)
{
if(current->data == item)
{
found = true;
break;
}
else
{
prev = current;
if(item > (current->data))
current = current->right;
else
current = current->left;
}
}
if (!found)
{
cout << item <<" not in Tree."<< endl;
return;
}
if((current->left==nullptr && current->right!= nullptr || (current->left != nullptr && current->right == nullptr))
{
if(current->left == nullptr && current->right != nullptr)
{
if(prev->left == current)
{
prev->left = current->right;
delete current;
current = nullptr;
cout << item <<" has been removed from the tree. "<<endl;
}
else
{
prev->right = current->right;
delete current;
current = nullptr;
cout << item <<" has been removed from the tree. "<<endl;
}
}
else
{
if(prev->left == current)
{
prev->left = current->left;
delete current;
current = nullptr;
cout << item <<" has been removed from the tree. "<<endl;
}
else
{
prev->right = current->left;
delete current;
current = nullptr;
cout << item <<" has been removed from the tree. "<<endl;
}
}
return;
}
if(current->left == nullptr && current->right == nullptr)
{
if(prev->left == current)
prev->left = nullptr;
else
prev->right = nullptr;
delete current;
cout << item <<" has been removed from the tree. "<<endl;
return;
}
if(current->left != nullptr && current->right != nullptr)
{
TreeNode *check = current->right;
if((current->left == nullptr) && (current->right != nullptr))
{
current = check;
delete check;
current->right == nullptr;
cout << item <<" has been removed from the tree. "<<endl;
}
else
{
if((current->right)->left != nullptr)
{
TreeNode *leftCurrent;
TreeNode *leftCurrentprev;
leftCurrentprev = current->right;
leftCurrent = (current->right)->left;
while(leftCurrent->left != nullptr)
{
leftCurrentprev = leftCurrent;
leftCurrent = leftCurrent->left;
}
current->data = leftCurrent->data;
delete leftCurrent;
leftCurrentprev-?left == nullptr;
cout << item << " has been removed from the tree. "<<endl;
}
else
{
TreeNode *temp = current->right;
current->data = temp->data;
current->right = temp->right;
delete temp;
cout << item <<" has been removed from the tree. "<<endl;
}
}
return;
}
}
Again we have an Unknown identifier type of "TreeNode" that keeps coming up as an error which I'm confused about since it doesn't come up for any other methods.
Possible case sensitivity related Typo?
You have a small 't' where you need a capital 'T' in:
template<class T> void BST<t>:: deleteNode(TreeNode *n, T item)