Im trying to figure out how to calculate the number of leaf nodes in a binary search tree.
I keep getting a run-time error and CodeBlocks keeps crashing at the final return statement. I've seen multiple examples on here and I still can't seem to understand where I'm going wrong.
I'm trying to do this recursively however as i stated previously as soon as i add the function number_of_leaves(p -> left)+ number_of_leaves(p-> right)
CodeBlocks stops working after it prints out:
Empty tree has 0 leaf nodes. Answer:0
Single node has 1 leaf node. Answer 1
Crashes here
.
#include <queue>
#include <stack>
#include <iostream>
#include <vector>
#include <stdlib.h>
#ifndef BINARY_SEARCH_TREE
#define BINARY_SEARCH_TREE
template<class T>
class Stack: public std::stack<T> {
public:
T pop() { T tmp = std::stack<T>::top(); std::stack<T>::pop(); return tmp; }
};
template<class T>
class Queue: public std::queue<T> {
public:
T dequeue() { T tmp = std::queue<T>::front(); std::queue<T>::pop(); return tmp; }
void enqueue(const T& el) { push(el); }
};
template<class T>
class BSTNode {
public:
BSTNode() { left = right = 0; }
BSTNode(const T& e, BSTNode<T> *l = 0, BSTNode<T> *r = 0)
{ el = e, left = l, right = r; }
T el;
BSTNode<T> *left, *right;
};
template<class T>
class BST {
public:
BST() { root = 0; }
~BST() { clear(); }
void clear() { clear(root), root = 0; }
bool is_empty() const { return root == 0; }
void preorder() { preorder(root); }
void inorder() { inorder(root); }
void postorder() { postorder(root); }
void insert(const T&);
T* search(const T& el) const { return search(root, el); }
void find_and_delete_by_copying(const T&);
void find_and_delete_by_merging(const T&);
void breadth_first();
void balance(std::vector<T>, int, int);
bool is_perfectly_balanced() const { return is_perfectly_balanced(root) >= 0; }
int number_of_leaves() const { return number_of_leaves(root); }
T* recursive_search(const T& el) const { return recursive_search(root, el); }
void recursive_insert(const T& el) { recursive_insert(root, el); }
protected:
void clear(BSTNode<T>*);
T* search(BSTNode<T>*, const T&) const;
void preorder(BSTNode<T>*);
void inorder(BSTNode<T>*);
void postorder(BSTNode<T>*);
virtual void visit(BSTNode<T>* p) // virtual allows re-definition in derived classes
{ std::cout << p->el << " "; }
void delete_by_copying(BSTNode<T>*&);
void delete_by_merging(BSTNode<T>*&);
int is_perfectly_balanced(BSTNode<T>*) const; // To be provided (A4)
int number_of_leaves(BSTNode<T>*) const; // To be provided (A4)
void recursive_insert(BSTNode<T>*&, const T&); // To be provided (P6)
T* recursive_search(BSTNode<T>*, const T&) const; // To be provided (P6)
BSTNode<T>* root;
};
#endif
template<class T>
void BST<T>::clear(BSTNode<T> *p)
{
if (p != 0) {
clear(p->left);
clear(p->right);
delete p;
}
}
template<class T>
void BST<T>::insert(const T& el)
{
BSTNode<T> *p = root, *prev = 0;
while (p != 0) { // find a place for inserting new node;
prev = p;
if (el < p->el)
p = p->left;
else
p = p->right;
}
if (root == 0) // tree is empty;
root = new BSTNode<T>(el);
else if (el < prev->el)
prev->left = new BSTNode<T>(el);
else
prev->right = new BSTNode<T>(el);
}
template<class T>
T* BST<T>::search(BSTNode<T>* p, const T& el) const
{
while (p != 0) {
if (el == p->el)
return &p->el;
else if (el < p->el)
p = p->left;
else
p = p->right;
}
return 0;
}
template<class T>
void BST<T>::inorder(BSTNode<T> *p)
{
if (p != 0) {
inorder(p->left);
visit(p);
inorder(p->right);
}
}
template<class T>
void BST<T>::preorder(BSTNode<T> *p)
{
if (p != 0) {
visit(p);
preorder(p->left);
preorder(p->right);
}
}
template<class T>
void BST<T>::postorder(BSTNode<T>* p)
{
if (p != 0) {
postorder(p->left);
postorder(p->right);
visit(p);
}
}
template<class T>
void BST<T>::delete_by_copying(BSTNode<T>*& node)
{
BSTNode<T> *previous, *tmp = node;
if (node->right == 0) // node has no right child;
node = node->left;
else if (node->left == 0) // node has no left child;
node = node->right;
else {
tmp = node->left; // node has both children;
previous = node; // 1.
while (tmp->right != 0) { // 2.
previous = tmp;
tmp = tmp->right;
}
node->el = tmp->el; // 3.
if (previous == node)
previous->left = tmp->left;
else
previous->right = tmp->left; // 4.
}
delete tmp; // 5.
}
// find_and_delete_by_copying() searches the tree to locate the node containing
// el. If the node is located, the function delete_by_copying() is called.
template<class T>
void BST<T>::find_and_delete_by_copying(const T& el)
{
BSTNode<T> *p = root, *prev = 0;
while (p != 0 && !(p->el == el)) {
prev = p;
if (el < p->el)
p = p->left;
else p = p->right;
}
if (p != 0 && p->el == el) {
if (p == root)
delete_by_copying(root);
else if (prev->left == p)
delete_by_copying(prev->left);
else
delete_by_copying(prev->right);
}
else if (root != 0)
std::cout << "el " << el << " is not in the tree" << std::endl;
else
std::cout << "the tree is empty" << std::endl;
}
template<class T>
void BST<T>::delete_by_merging(BSTNode<T>*& node)
{
BSTNode<T> *tmp = node;
if (node != 0) {
if (!node->right) // node has no right child: its left
node = node->left; // child (if any) is attached to its parent;
else if (node->left == 0) // node has no left child: its right
node = node->right; // child is attached to its parent;
else { // be ready for merging subtrees;
tmp = node->left; // 1. move left
while (tmp->right != 0) // 2. and then right as far as possible;
tmp = tmp->right;
tmp->right = // 3. establish the link between the
node->right; // the rightmost node of the left
// subtree and the right subtree;
tmp = node; // 4.
node = node->left; // 5.
}
delete tmp; // 6.
}
}
template<class T>
void BST<T>::find_and_delete_by_merging(const T& el)
{
BSTNode<T> *node = root, *prev = 0;
while (node != 0) {
if (node->el == el)
break;
prev = node;
if (el < node->el)
node = node->left;
else
node = node->right;
}
if (node != 0 && node->el == el) {
if (node == root)
delete_by_merging(root);
else if (prev->left == node)
delete_by_merging(prev->left);
else
delete_by_merging(prev->right);
}
else if (root != 0)
std::cout << "el " << el << " is not in the tree" << std::endl;
else
std::cout << "the tree is empty" << std::endl;
}
template<class T>
void BST<T>::breadth_first()
{
Queue<BSTNode<T>*> queue;
BSTNode<T> *p = root;
if (p != 0) {
queue.enqueue(p);
while (!queue.empty())
{
p = queue.dequeue();
visit(p);
if (p->left != 0)
queue.enqueue(p->left);
if (p->right != 0)
queue.enqueue(p->right);
}
}
}
template<class T>
void BST<T>::balance (std::vector<T> data, int first, int last)
{
if (first <= last) {
int middle = (first + last)/2;
insert(data[middle]);
balance(data,first,middle-1);
balance(data,middle+1,last);
}
}
template<class T>
void BST<T>::recursive_insert(BSTNode<T>*& p, const T& el)
{
if (p == 0) // Anchor case, tail recursion
p = new BSTNode<T>(el);
else if (el < p->el)
recursive_insert(p->left, el);
else
recursive_insert(p->right, el);
}
template<class T>
T* BST<T>::recursive_search(BSTNode<T>* p, const T& el) const
{
if (p != 0) {
if (el == p->el) // Anchor case, tail recursion
return &p->el;
else if (el < p->el)
return recursive_search(p->left, el);
else
return recursive_search(p->right, el);
}
else
return 0;
}
Problem is here***
I've tryed having a seperate counter to count the nodes, but it just prints all 0s. As soon as i add in the number_of_leaves() it crashes
template<class T>
int BST<T>::number_of_leaves(BSTNode<T>*) const {
BSTNode<T> *p = root;
if(p == NULL){
return 0;
}
if(p->left == NULL && p->right==NULL){
return 1;
}
else
return number_of_leaves(p->left) + number_of_leaves(p-> right);
}
Testing file below:
#include "BST.h"
#include <iostream>
using namespace std;
int main()
{
BST<int> a;
cout << "Empty tree has 0 leaf nodes. Answer: " << a.number_of_leaves() << endl;
a.insert(4);
cout << "Single node has 1 leaf node. Answer: " << a.number_of_leaves() << endl;
a.insert(2);
cout << "Linked list of 2 nodes has 1 leaf node. Answer: "
<< a.number_of_leaves() << endl;
a.insert(6);
cout << "Full binary tree of 3 nodes has 2 leaf nodes. Answer: "
<< a.number_of_leaves() << endl;
a.insert(3), a.insert(1), a.insert(5), a.insert(7);
cout << "Full binary tree of 7 nodes has 4 leaf nodes. Answer: "
<< a.number_of_leaves() << endl;
return 0;
}
In number_of_leaves(BSTNode<T>*), you discard the passed argument and always start from root. You then go down recursively and always do precisely the same operations, which leads to StackOverflow (sorry, I couldn't resist :p). You reach the maximum number of function calls and program is terminated.
template<class T>
int BST<T>::number_of_leaves(BSTNode<T>* start) const
{
if(start == NULL)
{
return 0;
}
if(start->left == NULL && start->right==NULL)
{
return 1;
}
return number_of_leaves(start->left) + number_of_leaves(start-> right);
}
Related
I'm currently working through AVL trees and am curious why the output (pre order traversal) is only showing two levels of indentation, as if one of the second order nodes is pointing to three separate 3rd level node. I'm note sure if this is an issue with my print function, or the actual code.
#include <iostream>
#include <list>
#include <vector>
#include <iomanip>
using namespace std;
template <class T>
class BST;
template <class T>
class BSTNode{
T data;
BSTNode<T>* parent;
BSTNode<T>* left;
BSTNode<T>* right;
int height;
public:
BSTNode(T data = T(), BSTNode<T>* parent = nullptr, BSTNode<T>* left = nullptr,
BSTNode<T>* right = nullptr, int height = 0) : data(data), parent(parent), left(left), right(right), height(height){}
friend class BST<T>;
int getSize() const;
};
template <class T>
class BST{
public:
BSTNode<T>* root = nullptr;
BST() {}
~BST();
BST(const BST& rhs) {*this = rhs;};
BST& operator=(const BST& rhs);
void printPreOrder(BSTNode<T>* p, int indent);
void insert(T item, BSTNode<T> * & node);
void remove(BSTNode<T>*& temp); //pass pointer by reference because we will be changing the pointer
void clear(BSTNode<T>*& root); //clears the entire tree;
BST<T>* clone(BSTNode<T>* start);
void rotateRight(BSTNode<T> * & node); //rotate the left child (the left child becomes the parent and parent becomes the right child)
void rotateLeft(BSTNode<T> * & node); //rotate the right child (the right child becomes the parent and the parent becomes the left child)
void doubleRotateRight(BSTNode<T> *& node); //same result as rotate right
void doubleRotateLeft(BSTNode<T> *& node); //same result as rotate left
int height(BSTNode<T> * node); //return height
void balance(BSTNode<T> * &node);
};
template <class T>
int BSTNode<T>::getSize() const {
int count = 1;
if(left != nullptr){
count += left->getSize();
};
if(right != nullptr){
count += right->getSize();
};
return count;
}
template <class T>
void BST<T>::printPreOrder(BSTNode<T>* p, int indent){
if(p) {
if (indent) {
std::cout << std::setw(indent) << '\t';
}
cout<< p->data << "\n ";
if(p->left) printPreOrder(p->left, indent+2);
if(p->right) printPreOrder(p->right, indent+2);
}
}
template <class T>
void BST<T>::insert(T item, BSTNode<T> * & node){
if(!node){
node = new BSTNode<T>(item);
}
else if(item < node->data){
insert(item, node->left);
}
else{
insert(item, node->right);
}
balance(node);
}
template <class T>
void BST<T>::remove(BSTNode<T>*& temp){
if(temp->left == nullptr && temp->right == nullptr){
if(temp->parent == nullptr){
root = nullptr;
}
else if(temp->parent->left == temp){
temp->parent->left = nullptr;
}
else{
temp->parent->right = nullptr;
}
delete temp;
}
else if(temp->left == nullptr){ //promote right
BSTNode<T>* toDelete = temp->right;
temp->data = toDelete->data;
temp->left = toDelete->left;
temp->right = toDelete->right;
if(temp->left){
temp->left->parent = temp->left;
}
if(temp->right){
temp->right->parent = temp;
}
delete toDelete;
}
else if(temp->right == nullptr){ //promote left
BSTNode<T>* toDelete = temp->left;
temp->data = toDelete->data;
temp->left = toDelete->left;
temp->right = toDelete->right;
if(temp->left){
temp->left->parent = temp->left;
}
if(temp->right){
temp->right->parent = temp;
}
delete toDelete;
}
else{
BSTNode<T>* maxOfLeft = temp->left;
while(maxOfLeft){
maxOfLeft = maxOfLeft->right;
}
temp->data = maxOfLeft->data;
remove(maxOfLeft);
}
balance(temp);
}
template <class T>
void BST<T>::clear(BSTNode<T>*& root) {
if (root) {
if (root->left) {
clear(root->left);
}
if (root->right) {
clear(root->right);
}
delete root;
}
root = nullptr;
};
template <class T>
BST<T>::~BST(){
clear(root);
}
template <class T>
BST<T>* BST<T>::clone(BSTNode<T>* start){
if(!start){
return nullptr;
}
else{
return new BSTNode<T>(start->data, clone(start->left), clone(start->right));
}
}
template <class T>
BST<T>& BST<T>::operator=(const BST<T>& rhs){
if(this == &rhs){
return *this;
}
clear(root);
root = clone(rhs.root);
return *this;
}
template <class T>
void BST<T>::rotateRight(BSTNode<T> * & node){
BSTNode<T> * newParent = node->left;
node->left = newParent->right;
newParent->right = node;
node->height = max(height(node->right),height(node->left)) + 1;
newParent->height = max(height(newParent->left), node->height) + 1;
node = newParent; //set new root (we can't access newParent outside of this function!)
}
template <class T>
void BST<T>::rotateLeft(BSTNode<T> * & node){
BSTNode<T> * newParent = node->right;
node->right = newParent->left;
newParent->left = node;
node->height = max(height(node->right), height(node->left)) + 1;
newParent->height = max(height(newParent->right), node->height) + 1;
node = newParent; //set new root (we can't access newParent outside of this function!)
}
template <class T>
int BST<T>::height(BSTNode<T> *node){
if(node){
return node->height;
};
return -1;
}
template <class T>
void BST<T>::doubleRotateRight(BSTNode<T> * &node){
rotateLeft(node->left);
rotateRight(node);
}
template<class T>
void BST<T>::doubleRotateLeft(BSTNode<T> * &node){
rotateRight(node->right);
rotateLeft(node);
}
template<class T>
void BST<T>::balance(BSTNode<T> * &node){
if(!node){
return;
}
if(height(node->left) > height(node->right) + 1){
if(height(node->left->left) >= height(node->left->right)){
rotateRight(node);
}
else{
doubleRotateRight(node);
};
};
if(height(node->right) > height(node->left) + 1){
if(height(node->right->right) >= height(node->right->left)){
rotateLeft(node);
}
else{
doubleRotateLeft(node);
}
}
node->height = max(height(node->right), height(node->left)) + 1;
}
int main() {
vector<int>data = {5, 3, 4, 2, 1, 2, 6, 7};
BST<int> test;
for(int r : data){
test.insert(r, test.root);
}
test.printPreOrder(test.root,0);
cout << endl;
return 0;
}
Here is the output I am getting:
3
2
1
2
5
4
6
7
From my understanding, I should be getting the following output:
3
2
1
2
5
4
6
7
Don't use tabs.
Consider this example:
#include <iostream>
#include <iomanip>
int main() {
for (int indent=0;indent<5;++indent) {
if (indent) {
std::cout << std::setw(indent) << "\t" << "tabs" << "\n";
std::cout << std::setw(indent) << " " << "spaces" << "\n";
}
}
}
Possible output is:
tabs
spaces
tabs
spaces
tabs
spaces
tabs
spaces
First off code:
`int main(int argc, char** argv)
{
fstream inFile;
inFile.open(argv[1]);
//where 'filename' is a string variable containing the filename
if (inFile.fail())
{
cerr<<"Error opening "<<argv[1]<<endl;
exit(1); //terminate the program
}
else{
string word;
AVLTree<WordStat> avl;
BSTree<WordStat> binary;
while(inFile >> word) {
WordStat a(word, 0);
avl.insert(a);
binary.insert(a);
}
cout << "Table 1:Binary Search Tree [" << argv[1] << "]" << endl;
cout << "In-order Traversal" << endl;
cout << "===================================" << endl;
cout << "Word Frequency" << endl;
cout << "----------------------------------" << endl;
while (binary.isEmpty() != true){
binary.traverse(printResults);
}`
Binary tree implementation:
template <typename E>
BSTree<E>::Node::Node(E s)
{
data = s;
left = NULL;
right = NULL;
}
/* Outer BSTree class definitions */
template <typename E>
BSTree<E>::BSTree()
{
root = NULL;
count = 0;
}
template <typename E>
BSTree<E>::~BSTree()
{
recDestroy(root);
}
template <typename E>
bool BSTree<E>::isEmpty() const
{
return root == NULL;
}
template<typename E>
void BSTree<E>::insert(E item)
{
Node* tmp;
Node* newnode = new Node(item);
/* If it is the first node in the tree */
if (isEmpty())
{
root = newnode;
count++;
return;
}
/*find where it should go */
tmp = root;
while (1)
{
if (tmp->data == item)
{ /* Key already exists. */
tmp->data = item;
delete newnode; /* don’t need it */
return;
}
else if (tmp->data > item)
{
if (!(tmp->left))
{
/* If the key is less than tmp */
tmp->left = newnode;
count++;
return;
}
else
{
/* continue searching for insertion pt. */
tmp = tmp->left;
}
}
else
{
if (!(tmp->right))
{
/* If the key is greater than tmp */
tmp->right = newnode;
count++;
return;
}
else
/* continue searching for insertion point*/
tmp = tmp->right;
}
}
}
template<typename E>
bool BSTree<E>::inTree(E item) const
{
Node* tmp;
if (isEmpty())
return false;
/*find where it is */
tmp = root;
while (1)
{
if (tmp->data == item)
return true;
if (tmp->data > item)
{
if (!(tmp->left))
return false;
/* continue searching */
tmp = tmp->left;
}
else
{
if (!(tmp->right))
return false;
/* continue searching for insertion pt. */
tmp = tmp->right;
}
}
}
template<typename E>
void BSTree<E>::remove(const E& item)
{
Node* nodeptr;
nodeptr = search(item);
if (nodeptr)
{
remove(nodeptr);
count--;
}
}
template<typename E>
const E& BSTree<E>::retrieve(const E& key) const throw (BSTreeException)
{
Node* tmp;
if (isEmpty())
throw BSTreeException("Binary Search Tree Exception: tree empty on retrieve()");
tmp = root;
while(tmp)
{
if (tmp->data == key)
return tmp->data;
if (tmp->data > key)
tmp = tmp->left;
else
tmp = tmp->right;
}
if (tmp == NULL)
throw BSTreeException("Binary Search Tree Exception: key does not exist on retrieve()");
return tmp->data;
}
template<typename E>
void BSTree<E>::traverse(FuncType func)
{
traverse(root,func);
}
template<typename E>
int BSTree<E>::size() const
{
return count;
}
template<typename E>
int BSTree<E>::height() const
{
return height(root);
}
template<typename E>
int BSTree<E>::depth(const E& item) const
{
Node* tmp;
tmp = root;
int depth;
while(tmp != NULL)
{
if (tmp->data == item)
return tmp->data;
if (tmp->data > item)
{
if (tmp->left == NULL)
break;
tmp = tmp->left;
depth++;
}
else
{
if (tmp->right == NULL)
break;
tmp = tmp->right;
depth++;
}
}
return depth;
}
template<typename E>
void BSTree<E>::recDestroy(Node* root)
{
if (root)
{
if (root->left) recDestroy(root->left);
if (root->right) recDestroy(root->right);
delete root;
}
}
template<typename E>
typename BSTree<E>::Node* BSTree<E>::findParent(Node* node)
{
Node* tmp;
tmp = root;
if (tmp == node)
return NULL;
while(1)
{
assert(tmp->data != node->data);
if (tmp->data > node->data)
{
assert(tmp->left != NULL);
if (tmp->left == node)
return tmp;
tmp = tmp->left;
}
else
{
assert(tmp->right != NULL);
if (tmp->right == node)
return tmp;
tmp = tmp->right;
}
}
}
template<typename E>
void BSTree<E>::traverse(Node* node, FuncType func)
{
if (node)
{
traverse(node->left,func);
func(node->data);
traverse(node->right,func);
}
}
template<typename E>
typename BSTree<E>::Node* BSTree<E>::search(const E& item)
{
Node* tmp;
tmp = root;
while(tmp)
{
if (tmp->data == item)
return tmp;
if (tmp->data > item)
tmp = tmp->left;
else
tmp = tmp->right;
}
return tmp;
}
template<typename E>
bool BSTree<E>::remove(Node* node)
{
E data;
Node* parent;
Node* replacement;
parent = findParent(node);
if (node->left && node->right)
{
replacement = node->right;
while (replacement->left)
replacement = replacement->left;
data = replacement->data;
remove(replacement);
node->data = data;
return true;
}
else
{
if (node->left)
replacement = node->left;
else if (node->right)
replacement = node->right;
else
replacement = NULL;
if (!parent)
root = replacement;
else if (parent->left == node)
parent->left = replacement;
else
parent->right = replacement;
delete node;
return true;
}
}
template<typename E>
int BSTree<E>::height(Node* node) const
{
int h = 0;
if (node != NULL)
{
int l_height = height(node->left);
int r_height = height(node->right);
int max_height = max(l_height, r_height);
h = max_height + 1;
}
return h;
}
template<typename E>
void BSTree<E>::levelTraverse(FuncType func)
{
queue<E> q;
q.push(root);
while (q.empty() != true){
Node *tmp = q.pop();
func(tmp);
q.push(tmp->left);
q.push(tmp->right);
}
}
When running the main above, it causes an error with the transverse function in the binary tree as follows "main.cpp:67:36: error: invalid conversion from 'void ()(WordStat)' to 'BSTree::FuncType {aka void ()(const WordStat&)}' [-fpermissive]
binary.traverse(printResults);"
Was wondering if anyone had any leads on fixing this. Thanks!
I think changing printResults interface to void printResults(const WordStat&) will solve the problem
I am using Visiual Studio 2013. For some reason, I am getting the following error:
Error 1 error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Word &)" (??6#YAAAV?$basic_ostream#DU?$char_traits#D#std###std##AAV01#AAVWord###Z) referenced in function "protected: virtual void __thiscall BST<class Word>::visit(class BSTNode<class Word> *)" (?visit#?$BST#VWord####MAEXPAV?$BSTNode#VWord#####Z) C:\Users\Reuben\documents\visual studio 2013\Projects\CS321 Lab4\CS321 Lab4\main.obj CS321 Lab4
The error is due to this particular line:
BST<Word> tree;
If the line were as follows, then it seems to compile just fine:
BST<int> tree;OR BST<string> tree;
So for some reason, it's not liking my implementation of the Word class I defined. Here is the following code.
main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "Word.h"
#include "genBST.h"
using namespace std;
int main()
{
BST<Word> tree;
system("pause");
return 0;
}
Word.h
#include <string>
#include <set>
using namespace std;
class Word{
public:
string* word;
set<int>* lineNums;
void addLineNum(int);
Word(string*, int);
Word();
friend ostream& operator<<(ostream& out, Word& pr);
friend bool operator==(Word, Word);
friend bool operator!=(Word, Word);
friend bool operator<(Word, Word);
friend bool operator<=(Word, Word);
friend bool operator>=(Word, Word);
friend bool operator>(Word, Word);
};
Word::Word(string* myWord, int myLineNum) {
word = myWord;
set<int>* lineNums = new set<int>();
lineNums->insert(myLineNum);
}
Word::Word()
{
word = new string("");
set<int>* lineNums = new set<int>();
lineNums->insert(1);
}
void Word::addLineNum(int line)
{
lineNums->insert(line);
}
//overload comparison operators
//take note that the order of these are important
//since some of the operators are defined in terms of the previously defined ones
bool operator==(Word word1, Word word2)
{
if (*(word1.word) == *(word2.word))
{
return true;
}
return false;
}
bool operator!=(Word word1, Word word2)
{
return !(word1 == word2);
}
bool operator<=(Word word1, Word word2)
{
if (*(word1.word) <= *(word2.word))
{
return true;
}
return false;
}
bool operator<(Word word1, Word word2)
{
if (word1 <= word2 && word1 != word2)
return true;
return false;
}
bool operator>(Word word1, Word word2)
{
return !(word1 <= word2);
}
bool operator>=(Word word1, Word word2)
{
return !(word1 < word2);
}
std::ostream& operator<<(std::ostream& out, const Word& word1)
{
out << *(word1.word);
out << ": ";
set<int>::iterator it;
for (it = word1.lineNums->begin(); it != word1.lineNums->end(); it++)
{
out << *it << " ";
}
return out;
}
The last file is genBST.h. It's a long file, so I'm posting it last. This file was given to me as part of my assignment and we are not allowed to make changes to this file or else we will lose points.
//************************ genBST.h **************************
// generic binary search tree
#include <queue>
#include <stack>
#ifndef BINARY_SEARCH_TREE
#define BINARY_SEARCH_TREE
template<class T>
class Stack : public stack<T> {
public:
T pop() {
T tmp = top();
stack<T>::pop();
return tmp;
}
};
template<class T>
class Queue : public queue<T> {
public:
T dequeue() {
T tmp = front();
queue<T>::pop();
return tmp;
}
void enqueue(const T& el) {
push(el);
}
};
template<class T> class BST;
template<class T>
class BSTNode {
public:
BSTNode() {
left = right = 0;
}
BSTNode(const T& e, BSTNode<T> *l = 0, BSTNode<T> *r = 0) {
el = e; left = l; right = r;
}
T el;
BSTNode<T> *left, *right;
};
template<class T>
class BST {
public:
BST() {
root = 0;
}
~BST() {
clear();
}
void clear() {
clear(root);
root = 0;
}
bool isEmpty() const {
return root == 0;
}
void preorder() {
preorder(root);
}
void inorder() {
inorder(root);
}
void postorder() {
postorder(root);
}
void insert(const T&);
void recursiveInsert(const T& el) {
recursiveInsert(root, el);
}
T* search(const T& el) const {
return search(root, el);
}
T* recursiveSearch(const T& el) const {
return recursiveSearch(root, el);
}
void deleteByCopying(BSTNode<T>*&);
void findAndDeleteByCopying(const T&);
void deleteByMerging(BSTNode<T>*&);
void findAndDeleteByMerging(const T&);
void iterativePreorder();
void iterativeInorder();
void iterativePostorder();
void breadthFirst();
void MorrisPreorder();
void MorrisInorder();
void MorrisPostorder();
void balance(T*, int, int);
protected:
BSTNode<T>* root;
void clear(BSTNode<T>*);
void recursiveInsert(BSTNode<T>*&, const T&);
T* search(BSTNode<T>*, const T&) const;
T* recursiveSearch(BSTNode<T>*, const T&) const;
void preorder(BSTNode<T>*);
void inorder(BSTNode<T>*);
void postorder(BSTNode<T>*);
virtual void visit(BSTNode<T>* p)
{
cout << p->el << ' ';
}
};
template<class T>
void BST<T>::clear(BSTNode<T> *p) {
if (p != 0) {
clear(p->left);
clear(p->right);
delete p;
}
}
template<class T>
void BST<T>::insert(const T& el) {
BSTNode<T> *p = root, *prev = 0;
while (p != 0) { // find a place for inserting new node;
prev = p;
if (el < p->el)
p = p->left;
else p = p->right;
}
if (root == 0) // tree is empty;
root = new BSTNode<T>(el);
else if (el < prev->el)
prev->left = new BSTNode<T>(el);
else prev->right = new BSTNode<T>(el);
}
template<class T>
void BST<T>::recursiveInsert(BSTNode<T>*& p, const T& el) {
if (p == 0)
p = new BSTNode<T>(el);
else if (el < p->el)
recursiveInsert(p->left, el);
else recursiveInsert(p->right, el);
}
template<class T>
T* BST<T>::search(BSTNode<T>* p, const T& el) const {
while (p != 0)
if (el == p->el)
return &p->el;
else if (el < p->el)
p = p->left;
else p = p->right;
return 0;
}
template<class T>
T* BST<T>::recursiveSearch(BSTNode<T>* p, const T& el) const {
if (p != 0)
if (el == p->el)
return &p->el;
else if (el < p->el)
return recursiveSearch(p->left, el);
else return recursiveSearch(p->right, el);
else return 0;
}
template<class T>
void BST<T>::inorder(BSTNode<T> *p) {
if (p != 0) {
inorder(p->left);
visit(p);
inorder(p->right);
}
}
template<class T>
void BST<T>::preorder(BSTNode<T> *p) {
if (p != 0) {
visit(p);
preorder(p->left);
preorder(p->right);
}
}
template<class T>
void BST<T>::postorder(BSTNode<T>* p) {
if (p != 0) {
postorder(p->left);
postorder(p->right);
visit(p);
}
}
template<class T>
void BST<T>::deleteByCopying(BSTNode<T>*& node) {
BSTNode<T> *previous, *tmp = node;
if (node->right == 0) // node has no right child;
node = node->left;
else if (node->left == 0) // node has no left child;
node = node->right;
else {
tmp = node->left // node has both children;
previous = node; // 1.
while (tmp->right != 0) { // 2.
previous = tmp;
tmp = tmp->right;
}
node->el = tmp->el; // 3.
if (previous == node)
previous->left = tmp->left;
else previous->right = tmp->left; // 4.
}
delete tmp; // 5.
}
// findAndDeleteByCopying() searches the tree to locate the node containing
// el. If the node is located, the function DeleteByCopying() is called.
template<class T>
void BST<T>::findAndDeleteByCopying(const T& el) {
BSTNode<T> *p = root, *prev = 0;
while (p != 0 && !(p->el == el)) {
prev = p;
if (el < p->el)
p = p->left;
else p = p->right;
}
if (p != 0 && p->el == el)
if (p == root)
deleteByCopying(root);
else if (prev->left == p)
deleteByCopying(prev->left);
else deleteByCopying(prev->right);
else if (root != 0)
cout << "el " << el << " is not in the tree\n";
else cout << "the tree is empty\n";
}
template<class T>
void BST<T>::deleteByMerging(BSTNode<T>*& node) {
BSTNode<T> *tmp = node;
if (node != 0) {
if (!node->right) // node has no right child: its left
node = node->left; // child (if any) is attached to its parent;
else if (node->left == 0) // node has no left child: its right
node = node->right; // child is attached to its parent;
else { // be ready for merging subtrees;
tmp = node->left; // 1. move left
while (tmp->right != 0)// 2. and then right as far as possible;
tmp = tmp->right;
tmp->right = // 3. establish the link between the
node->right; // the rightmost node of the left
// subtree and the right subtree;
tmp = node; // 4.
node = node->left; // 5.
}
delete tmp; // 6.
}
}
template<class T>
void BST<T>::findAndDeleteByMerging(const T& el) {
BSTNode<T> *node = root, *prev = 0;
while (node != 0) {
if (node->el == el)
break;
prev = node;
if (el < node->el)
node = node->left;
else node = node->right;
}
if (node != 0 && node->el == el)
if (node == root)
deleteByMerging(root);
else if (prev->left == node)
deleteByMerging(prev->left);
else deleteByMerging(prev->right);
else if (root != 0)
cout << "el " << el << " is not in the tree\n";
else cout << "the tree is empty\n";
}
template<class T>
void BST<T>::iterativePreorder() {
Stack<BSTNode<T>*> travStack;
BSTNode<T> *p = root;
if (p != 0) {
travStack.push(p);
while (!travStack.empty()) {
p = travStack.pop();
visit(p);
if (p->right != 0)
travStack.push(p->right);
if (p->left != 0) // left child pushed after right
travStack.push(p->left); // to be on the top of the stack;
}
}
}
template<class T>
void BST<T>::iterativeInorder() {
Stack<BSTNode<T>*> travStack;
BSTNode<T> *p = root;
while (p != 0) {
while (p != 0) { // stack the right child (if any)
if (p->right) // and the node itself when going
travStack.push(p->right); // to the left;
travStack.push(p);
p = p->left;
}
p = travStack.pop(); // pop a node with no left child
while (!travStack.empty() && p->right == 0) { // visit it and all nodes
visit(p); // with no right child;
p = travStack.pop();
}
visit(p); // visit also the first node with
if (!travStack.empty()) // a right child (if any);
p = travStack.pop();
else p = 0;
}
}
template<class T>
void BST<T>::iterativePostorder() {
Stack<BSTNode<T>*> travStack;
BSTNode<T>* p = root, *q = root;
while (p != 0) {
for (; p->left != 0; p = p->left)
travStack.push(p);
while (p->right == 0 || p->right == q) {
visit(p);
q = p;
if (travStack.empty())
return;
p = travStack.pop();
}
travStack.push(p);
p = p->right;
}
}
template<class T>
void BST<T>::breadthFirst() {
Queue<BSTNode<T>*> queue;
BSTNode<T> *p = root;
if (p != 0) {
queue.enqueue(p);
while (!queue.empty()) {
p = queue.dequeue();
visit(p);
if (p->left != 0)
queue.enqueue(p->left);
if (p->right != 0)
queue.enqueue(p->right);
}
}
}
template<class T>
void BST<T>::MorrisInorder() {
BSTNode<T> *p = root, *tmp;
while (p != 0)
if (p->left == 0) {
visit(p);
p = p->right;
}
else {
tmp = p->left;
while (tmp->right != 0 &&// go to the rightmost node of
tmp->right != p) // the left subtree or
tmp = tmp->right; // to the temporary parent of p;
if (tmp->right == 0) { // if 'true' rightmost node was
tmp->right = p; // reached, make it a temporary
p = p->left; // parent of the current root,
}
else { // else a temporary parent has been
visit(p); // found; visit node p and then cut
tmp->right = 0; // the right pointer of the current
p = p->right; // parent, whereby it ceases to be
} // a parent;
}
}
template<class T>
void BST<T>::MorrisPreorder() {
BSTNode<T> *p = root, *tmp;
while (p != 0) {
if (p->left == 0) {
visit(p);
p = p->right;
}
else {
tmp = p->left;
while (tmp->right != 0 &&// go to the rightmost node of
tmp->right != p) // the left subtree or
tmp = tmp->right; // to the temporary parent of p;
if (tmp->right == 0) { // if 'true' rightmost node was
visit(p); // reached, visit the root and
tmp->right = p; // make the rightmost node a temporary
p = p->left; // parent of the current root,
}
else { // else a temporary parent has been
tmp->right = 0; // found; cut the right pointer of
p = p->right; // the current parent, whereby it ceases
} // to be a parent;
}
}
}
template<class T>
void BST<T>::MorrisPostorder() {
BSTNode<T> *p = new BSTNode<T>(), *tmp, *q, *r, *s;
p->left = root;
while (p != 0)
if (p->left == 0)
p = p->right;
else {
tmp = p->left;
while (tmp->right != 0 &&// go to the rightmost node of
tmp->right != p) // the left subtree or
tmp = tmp->right; // to the temporary parent of p;
if (tmp->right == 0) { // if 'true' rightmost node was
tmp->right = p; // reached, make it a temporary
p = p->left; // parent of the current root,
}
else { // else a temporary parent has been found;
// process nodes between p->left (included) and p (excluded)
// extended to the right in modified tree in reverse order;
// the first loop descends this chain of nodes and reverses
// right pointers; the second loop goes back, visits nodes,
// and reverses right pointers again to restore the pointers
// to their original setting;
for (q = p->left, r = q->right, s = r->right;
r != p; q = r, r = s, s = s->right)
r->right = q;
for (s = q->right; q != p->left;
q->right = r, r = q, q = s, s = s->right)
visit(q);
visit(p->left); // visit node p->left and then cut
tmp->right = 0; // the right pointer of the current
p = p->right; // parent, whereby it ceases to be
} // a parent;
}
}
template<class T>
void BST<T>::balance(T data[], int first, int last) {
if (first <= last) {
int middle = (first + last) / 2;
insert(data[middle]);
balance(data, first, middle - 1);
balance(data, middle + 1, last);
}
}
#endif
Any help would be appreciated! I'm still learning the basics of c++, I transferred schools so I'm trying to learn c++ (as opposed to Java which is what I was doing before at my other school). Thanks in advance!
EDIT: Oops, I was being dumb, the following line of code:
friend ostream& operator<<(ostream& out, Word& pr);
Should be (I think):
friend ostream& operator<<(ostream, const Word);
However, after this change, I still get the following error:
Error 1 error C2593: 'operator <<' is ambiguous c:\users\reuben\documents\visual studio 2013\projects\cs321 lab4\cs321 lab4\genbst.h 105 1 CS321 Lab4
Where the line 105 refers is the statement in the function (in the genBST.h file):
virtual void visit(BSTNode<T>* p)
{
cout << p->el << ' ';
}
EDIT v2:
Ok, I've changed the code and it seems to work now. I just placed the implementation of the << operator inside the declaration like so:
class Word{
public:
string* word;
set<int>* lineNums;
void addLineNum(int);
Word(string*, int);
Word();
friend ostream& operator<<(ostream& out, const Word& word1 )
{
out << *(word1.word);
out << ": ";
set<int>::iterator it;
for (it = word1.lineNums->begin(); it != word1.lineNums->end(); it++)
{
out << *it << " ";
}
return out;
};
friend bool operator==(Word, Word);
friend bool operator!=(Word, Word);
friend bool operator<(Word, Word);
friend bool operator<=(Word, Word);
friend bool operator>=(Word, Word);
friend bool operator>(Word, Word);
};
And it seems to work now.
I noticed that in your class definition you have:
class Word{
public:
string* word;
set<int>* lineNums;
void addLineNum(int);
Word(string*, int);
Word();
friend ostream& operator<<(ostream& out, Word& pr);
there is no const before Word & pr
however later in your code you have:
std::ostream& operator<<(std::ostream& out, const Word& word1)
see , there is a const here before Word& word1
should make them same( both have const), I think
I tried your code on my Visual Stdio 2010 ( I do not have 2013).
Before I adding the keyword const (before Word & pr) I got same error as you.
However, after I added the const, it was built successfully.
What is the error you got after you add the keyword const ? Post in detail here.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hi I am getting an access violation reading error in my linked list header file. The project takes a binary tree and turns it into an ordered linked list. the binary tree header:
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
#include "dsexceptions.h"
#include "LinkedList.h"
#include <iostream>
using namespace std;
template <typename Comparable>
class BinarySearchTree
{
public:
BinarySearchTree( ) :root( NULL )
{ }
BinarySearchTree(const BinarySearchTree & rhs) : root(NULL)
{ *this = rhs; }
~BinarySearchTree( )
{ makeEmpty( ); }
const Comparable & findMin( ) const
{
if (isEmpty( ))
throw UnderflowException( );
return findMin(root)->element;
}
const Comparable & findMax( ) const
{
if(isEmpty( ))
throw UnderflowException( );
return findMax( root )->element;
}
bool contains(const Comparable & x) const
{ return contains(x, root); }
bool isEmpty( ) const
{ return root == NULL; }
void printTree(ostream & out = cout)
{
if (isEmpty( ))
out << "Empty tree" << endl;
else
printTree(root, out);
}
void makeEmpty( )
{ makeEmpty(root); }
void insert(const Comparable & x)
{ insert(x, root); }
void remove(const Comparable & x)
{ remove(x, root); }
const BinarySearchTree & operator=(const BinarySearchTree & rhs)
{
if (this != &rhs)
{
makeEmpty( );
root = clone(rhs.root);
}
return *this;
}
void toList(linkedlist l)
{ toList(l, root); }
private:
struct BinaryNode
{
Comparable element;
BinaryNode *left;
BinaryNode *right;
BinaryNode(const Comparable & theElement, BinaryNode *lt, BinaryNode *rt)
: element(theElement), left(lt), right(rt) { }
};
BinaryNode *root;
void toList(linkedlist l, BinaryNode *&t)
{
if(t==NULL)
{ return; }
toList(l,t->left);
l.add(t->element);
toList(l,t->right);
}
void printTree(BinaryNode *&t, ostream & out = cout)
{
if(t==NULL)
{ return; }
printTree(t->left,out);
cout << t->element << endl;
printTree(t->right,out);
}
void insert(const Comparable & x, BinaryNode * & t)
{
if (t == NULL)
t = new BinaryNode(x, NULL, NULL);
else if (x < t->element)
insert(x, t->left);
else if (t->element < x)
insert(x, t->right);
else; // Duplicate; do nothing
}
void remove(const Comparable & x, BinaryNode * & t)
{
if (t == NULL)
return; // Item not found; do nothing
if (x < t->element)
remove(x, t->left);
else if (t->element < x)
remove(x, t->right);
else if (t->left != NULL && t->right != NULL) // Two children
{
t->element = findMin(t->right)->element;
remove(t->element, t->right);
}
else
{
BinaryNode *oldNode = t;
t = (t->left != NULL) ? t->left : t->right;
delete oldNode;
}
}
BinaryNode * findMin(BinaryNode *t) const
{
if (t == NULL)
return NULL;
if (t->left == NULL)
return t;
return findMin(t->left);
}
BinaryNode * findMax(BinaryNode *t) const
{
if (t != NULL)
while (t->right != NULL)
t = t->right;
return t;
}
bool contains(const Comparable & x, BinaryNode *t) const
{
if (t == NULL)
return false;
else if (x < t->element)
return contains(x, t->left);
else if (t->element < x)
return contains(x, t->right);
else
return true; // Match
}
void makeEmpty(BinaryNode * & t)
{
if (t != NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL;
}
BinaryNode * clone(BinaryNode *t) const
{
if (t == NULL)
return NULL;
else
return new BinaryNode(t->element, clone(t->left), clone(t->right));
}
};
#endif
the linked list header:
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#include <iostream>
using namespace std;
class linkedlist
{
private:
struct lNode{
int data;
lNode *next;
};
struct lNode *head;
public:
linkedlist()
{ struct lNode *head = new lNode;
head->next = NULL;
}
void add(int n) {
lNode *newlNode = new lNode;
newlNode->data = n;
newlNode->next = NULL;
lNode *cur = head;
while(true) {
if(cur->next == NULL)
{
cur->next = newlNode;
break;
}
cur = cur->next;
}
}
void display() {
lNode *list = head;
while(true)
{
if (list->next == NULL)
{
cout << list->data << endl;
break;
}
cout << list->data << endl;
list = list->next;
}
cout << "done" << endl;
}
};
#endif
the main cpp file:
#include <iostream>
#include "BinarySearchTree.h"
#include "LinkedList.h"
using namespace std;
int main( )
{
BinarySearchTree<int> t;
linkedlist l;
int i;
cout << "inserting nodes into tree" << endl;
t.insert(50);
t.insert(60);
t.insert(30);
t.insert(20);
t.insert(40);
t.insert(70);
t.insert(55);
t.insert(65);
t.insert(25);
t.insert(35);
t.insert(85);
t.insert(100);
t.insert(15);
t.insert(45);
t.insert(95);
t.insert(105);
t.insert(10);
t.insert(75);
t.insert(110);
t.insert(12);
t.insert(92);
t.insert(32);
t.insert(82);
t.insert(22);
t.insert(32);
t.printTree( );
t.toList(l);
cout << "Finished processing" << endl;
l.display();
return 0;
}
The location of the error is in the linked list header file here: if(cur->next == NULL). I do not see how it could be an access error as everything is contained inside that class.
In the code above you have this section of code:
struct lNode *head;
public:
linkedlist()
{ struct lNode *head = new lNode;
head->next = NULL;
}
That code is defining two instances of the head node which I'm sure is not what you want.
The ctor should be something more like this:
linkedlist()
{
head = new lNode;
head->next = NULL;
}
Your code does not test for the empty list -- that is where there are no elements in the list and the head is NULL.
Also, you are missing any constructors which is initializing the class, so it may very well be that head has an undefined value -- also there add method make not use of the loop, or make any recording of the added elements...
So in short, there are a lot of programming issues to fix.
I have a problem with this Binary Search Tree.
After that i cut a leave, if I try to show the tree VisualStudio answer me this message
An unhandled exception of type 'System.AccessViolationException' occurred in ABR1.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
It's more that 3 days that i try to understand could someone help me???
// ABR1.cpp : main project file.
#include "stdafx.h"
#include <iostream>
using namespace System;
using namespace std;
template <class T>
class ABR{
private:
struct Leaf{
T value;
struct Leaf *DX; //
struct Leaf *SX; //
};
Leaf *root;
public:
//constructors
ABR() { root = NULL; }
//destructor
//~ABR();
void appendLeaf(T);
bool cutLeaf(T);
bool isInTree(T) const;
Leaf* findLeaf(T) const;
void showTreeInOrder() const { showTreeInOrder(root); }
void showTreeInOrder(Leaf *) const;
void showTreePreOrder() const { showTreePreOrder(root); }
void showTreePreOrder(Leaf *) const;
};
template <class T>
void ABR<T>::appendLeaf(T newValue){
if (isInTree(newValue)){
cout << "The value is just present..." << endl;
return;
}
Leaf *newLeaf; // To point to a new leaf
Leaf *ptrLeaf; // To move in the tree
// Allocate the necessary memory
newLeaf = new Leaf; //generate the new leaf
newLeaf-> value = newValue;
newLeaf-> DX = NULL;
newLeaf-> SX = NULL;
if(!root) //if is the first leaf
root = newLeaf;
else{
ptrLeaf = root;
//cout<<ptrLeaf->value<<ptrLeaf->SX<<ptrLeaf->DX<<endl;
while (ptrLeaf != NULL){
//cout << ptrLeaf->value <<"\t";
if (ptrLeaf->value < newValue){
if (ptrLeaf->DX == NULL){
ptrLeaf->DX = newLeaf;
return;
}
else
ptrLeaf = ptrLeaf->DX;
}
else{
if(ptrLeaf->SX == NULL){
ptrLeaf->SX = newLeaf;
return;
}
else
ptrLeaf = ptrLeaf->SX;
}
}
}
}
template <class T>
bool ABR<T>::isInTree(T toFind) const{
Leaf *ptrLeaf;
ptrLeaf = root;
while (ptrLeaf){
if (ptrLeaf->value == toFind)
return true;
else{
if (ptrLeaf->value < toFind)
ptrLeaf = ptrLeaf->DX;
else
ptrLeaf = ptrLeaf->SX;
}
}
return false;
}
template <class T>
typename ABR<T>::Leaf * ABR<T>::findLeaf(T toFind) const
{
Leaf *ptr;
ptr = root;
while(ptr != NULL)
{
//cout << ptr->value << "#" << endl;
if (toFind == ptr->value){
//cout << "Trovato";
return ptr;
}
else if (ptr->value < toFind)
ptr = ptr->DX;
else
ptr = ptr->SX;
} cout << "Element don't find" << endl;
return NULL;
}
template <class T>
void ABR<T>::showTreeInOrder(Leaf *ptr) const
{
if(ptr != NULL)
{
showTreeInOrder(ptr->SX);
cout << ptr->value << endl;
showTreeInOrder(ptr->DX);
}
}
template <class T>
void ABR<T>::showTreePreOrder(Leaf *ptr) const
{
if(ptr != NULL)
{
showTreePreOrder(ptr->DX);
cout << ptr->value << endl;
showTreePreOrder(ptr->SX);
}
}
template <class T>
bool ABR<T>::cutLeaf(T toCut)
{
Leaf *Leafptr, *tempLeafptr;
Leafptr = findLeaf(toCut);
if (Leafptr == NULL)
{
cout << "The element is not present..." << endl;
return false;
}
else if (Leafptr->DX == NULL)
{
tempLeafptr = Leafptr;
Leafptr = Leafptr->SX;
delete tempLeafptr;
return true;
}
else if (Leafptr->SX == NULL)
{
tempLeafptr = Leafptr;
Leafptr = Leafptr->DX;
delete tempLeafptr;
return true;
}
else
{
tempLeafptr = Leafptr->DX;
while (tempLeafptr->SX)
tempLeafptr = tempLeafptr->SX;
tempLeafptr->DX = Leafptr->SX;
tempLeafptr = Leafptr;
Leafptr = Leafptr->DX;
delete tempLeafptr;
return true;
}
}
int main(){
ABR<int> albero;
for(int a = 0.0; a < 100.0; a+= 3)
albero.appendLeaf(a);
albero.appendLeaf(1000);
albero.appendLeaf(1001);
albero.showTreePreOrder();
int b = 75;
albero.cutLeaf(b);
albero.showTreePreOrder(); //ERROR
//albero.showTreeInOrder();//SAME ERROR
system("PAUSE");
return 0;
}
You're recursing in showTreePreOrder and encountering a stack overflow. Running it in the debugger told me this in under one minute.
EDIT:
Your problem is in this section of cutLeaf(). First, you're assuming Leafptr->SX isn't null and you're deleting it, but it is null for the last leaf. Second, when you delete the leaf you don't set its parent's DX pointer to null. Therefore, when you traverse the list, you traverse into leaves that have been freed.
else if (Leafptr->DX == NULL)
{
tempLeafptr = Leafptr;
Leafptr = Leafptr->SX;
delete tempLeafptr;
return true;
}
The same problems exist in the else clause.