I'm implementing a bst, more precisely an AVL tree in c++. I got pretty much everything working except the balancing. The program will crash when it tries to balance LR or RL. For example if will crash if i insert 7, 5, 6 OR 7, 9, 8 but it will work with: 7, 6, 5 AND 7, 8, 9.
relevant code(pastebin): https://pastebin.com/cn69XLn5
relevant code:
//RIGHT RIGHT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::RRrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->rightChild;
rootptr->rightChild = temp->leftChild;
temp->leftChild = rootptr;
return temp;
}
//LEFT LEFT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::LLrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->leftChild;
rootptr->leftChild = temp->rightChild;
temp->rightChild = rootptr;
return temp;
}
//LEFT RIGHT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::LRrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->leftChild;
rootptr->leftChild = RRrotation(temp);
return LLrotation(rootptr);
}
//RIGHT LEFT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::RLrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->rightChild;
rootptr->rightChild = LLrotation(temp);
return RRrotation(rootptr);
}
// There are four different rotation scenarios, two simpler and two harder.
// check what rotation is needed and then send forward to that rotation
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::balanceFactory(bstNode* rootptr)
{
//std::cout << rootptr->value << std::endl;
int BF = balanceFactor();
if (BF > 1) //use == 2 instead?
{
if (balanceFactorLeftChild() > 0) //perform left left rotation
{
rootptr = LLrotation(rootptr);
}else //perform left right rotation
{
rootptr = LRrotation(rootptr);
}
}
else if (BF < -1)
{
if (balanceFactorRightChild() > 0) // perform right left rotation
{
rootptr = RLrotation(rootptr);
}else
{
rootptr = RRrotation(rootptr); // the last option, which is right right rotation
}
}
return rootptr;
}
template <typename x_type>
void AVLTree<x_type>::insert(x_type value){
insert(&(this->rootptr), value);
}
template <typename x_type>
void AVLTree<x_type>::insert(bstNode** rootptr, x_type value)
{
if (*rootptr == nullptr)
{
//this tree is empty
*rootptr = createNewNode(value);
}
else if ((*rootptr)->value == value) //if value already in tree, dont insert again, just break
{
return;
}else if (value <= (*rootptr)->value)
{
//insert at left side using recursion
insert(&(*rootptr)->leftChild, value);
*rootptr = balanceFactory(*rootptr);
}else if (value >= (*rootptr)->value)
{
//insert at right side using recursion
insert(&(*rootptr)->rightChild, value);
*rootptr = balanceFactory(*rootptr);
}
}
all code (pastebin): https://pastebin.com/uxTQ369i
all code:
//avl tree emil wallin
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
template <typename x_type>
class AVLTree {
struct bstNode {
x_type value;
bstNode* leftChild;
bstNode* rightChild;
};
//bstNode* rootptr;
public:
AVLTree();
bstNode* createNewNode(x_type value);
int balanceFactor();
int balanceFactorLeftChild();
int balanceFactorRightChild();
bstNode* RRrotation(bstNode* rootptr);
bstNode* LLrotation(bstNode* rootptr);
bstNode* LRrotation(bstNode* rootptr);
bstNode* RLrotation(bstNode* rootptr);
bstNode* balanceFactory(bstNode* rootptr);
void insert(x_type value);
void remove(x_type value);
bool find(x_type value);
std::vector<x_type>preOrderWalk();
std::vector<x_type>inOrderWalk();
std::vector<x_type>postOrderWalk();
x_type getMin();
x_type getMax();
x_type maxVal(x_type a, x_type b);
size_t getTreeHeight();
bstNode* get_rootptr(){return rootptr;}
private:
bstNode* rootptr;
int balanceFactor(bstNode* rootptr);
void insert(bstNode** rootptr, x_type value);
void remove(bstNode*, x_type value);
bool find(bstNode* rootptr, x_type value);
std::vector<x_type> preOrderWalk(bstNode* rootptr);
std::vector<x_type> inOrderWalk(bstNode* rootptr);
std::vector<x_type> postOrderWalk(bstNode* rootptr);
x_type getMin(bstNode* rootptr);
x_type getMax(bstNode* rootptr);
size_t getTreeHeight(bstNode* rootptr);
};
//this is a constructor:
template <typename x_type>
AVLTree<x_type>::AVLTree()
{
this->rootptr = nullptr;
}
//dynamically allocate new memory for a node, using keyword new
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::createNewNode(x_type value)
{
bstNode* newNode = new bstNode();
(*newNode).value = value;
newNode->leftChild = nullptr;
newNode->rightChild = nullptr;
return newNode;
}
template <typename x_type>
int AVLTree<x_type>::balanceFactorLeftChild()
{
return balanceFactor(this->rootptr->leftChild);
}
template <typename x_type>
int AVLTree<x_type>::balanceFactorRightChild()
{
return balanceFactor(this->rootptr->rightChild);
}
template <typename x_type>
int AVLTree<x_type>::balanceFactor()
{
return balanceFactor(this->rootptr);
}
template <typename x_type>
int AVLTree<x_type>::balanceFactor(bstNode* rootptr)
{
int leftHeight = getTreeHeight(rootptr->leftChild);
int rightHeight = getTreeHeight(rootptr->rightChild);
int balanceNumber = leftHeight - rightHeight;
return balanceNumber;
}
//RIGHT RIGHT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::RRrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->rightChild;
rootptr->rightChild = temp->leftChild;
temp->leftChild = rootptr;
return temp;
}
//LEFT LEFT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::LLrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->leftChild;
rootptr->leftChild = temp->rightChild;
temp->rightChild = rootptr;
return temp;
}
//LEFT RIGHT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::LRrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->leftChild;
rootptr->leftChild = RRrotation(temp);
return LLrotation(rootptr);
}
//RIGHT LEFT ROTATION
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::RLrotation(bstNode* rootptr)
{
bstNode* temp;
temp = rootptr->rightChild;
rootptr->rightChild = LLrotation(temp);
return RRrotation(rootptr);
}
// There are four different rotation scenarios, two simpler and two harder.
// check what rotation is needed and then send forward to that rotation
template <typename x_type>
typename AVLTree<x_type>::bstNode* AVLTree<x_type>::balanceFactory(bstNode* rootptr)
{
//std::cout << rootptr->value << std::endl;
int BF = balanceFactor();
if (BF > 1) //use == 2 instead?
{
if (balanceFactorLeftChild() > 0) //perform left left rotation
{
rootptr = LLrotation(rootptr);
}else //perform left right rotation
{
rootptr = LRrotation(rootptr);
}
}
else if (BF < -1)
{
if (balanceFactorRightChild() > 0) // perform right left rotation
{
rootptr = RLrotation(rootptr);
}else
{
rootptr = RRrotation(rootptr); // the last option, which is right right rotation
}
}
return rootptr;
}
template <typename x_type>
void AVLTree<x_type>::insert(x_type value){
insert(&(this->rootptr), value);
}
template <typename x_type>
void AVLTree<x_type>::insert(bstNode** rootptr, x_type value)
{
if (*rootptr == nullptr)
{
//this tree is empty
*rootptr = createNewNode(value);
}
else if ((*rootptr)->value == value) //if value already in tree, dont insert again, just break
{
return;
}else if (value <= (*rootptr)->value)
{
//insert at left side using recursion
insert(&(*rootptr)->leftChild, value);
*rootptr = balanceFactory(*rootptr);
}else if (value >= (*rootptr)->value)
{
//insert at right side using recursion
insert(&(*rootptr)->rightChild, value);
*rootptr = balanceFactory(*rootptr);
}
}
template <typename x_type>
void AVLTree<x_type>::remove(x_type value)
{
remove(this->rootptr, value);
}
template <typename x_type>
void AVLTree<x_type>::remove(bstNode* rootptr, x_type value)
{
if (rootptr == nullptr)
{
return; //there is no data in tree
} else if (value > rootptr->value) // go to right subtree
{
remove(rootptr->rightChild, value);
} else if (value < rootptr->value) // go to left subtree
{
remove(rootptr->leftChild, value);
}
else // if its not greater nor less, it must be equal, therefore we found the node to be removed
{
//there are three different situations.
//the node we must remove can have 0 children -> 1.
//the node we must remove can have 1 child -> 2.
//the node we must remove can have 2 children -> 3.
//1:
if (rootptr->leftChild == nullptr && rootptr->rightChild == nullptr)
{
delete rootptr;
rootptr = nullptr;
}
//2:
else if (rootptr->leftChild == nullptr)
{
bstNode* tempPtr = rootptr;
rootptr = rootptr->rightChild;
delete tempPtr;
}
//2 (other child):
else if (rootptr->rightChild == nullptr)
{
bstNode* tempPtr = rootptr;
rootptr = rootptr->leftChild;
delete tempPtr;
}
//3:
else
{
//bstNode<x_type>* tempPtr = getMin(rootptr->rightChild);
bstNode* tempPtr = rootptr;
tempPtr->value = getMax(rootptr->leftChild);
rootptr->value = tempPtr->value;
remove(rootptr->leftChild, tempPtr->value);
}
}
return;
}
template <typename x_type>
bool AVLTree<x_type>::find(x_type value)
{
return find(this->rootptr, value);
}
template <typename x_type>
bool AVLTree<x_type>::find(bstNode* rootptr, x_type value)
{
if (rootptr == nullptr)
{
//either the tree is empty
return false;
}else if (rootptr->value == value)
{
//value found
return true;
}else if (value <= rootptr->value)
{
return find(rootptr->leftChild, value);
}else if (value >= rootptr->value)
{
return find(rootptr->rightChild, value);
}
return false;
}
template <typename x_type>
std::vector<x_type> AVLTree<x_type>::preOrderWalk(){
return preOrderWalk(this->rootptr);
}
template <typename x_type>
std::vector<x_type> AVLTree<x_type>::preOrderWalk(bstNode* rootptr)
{
std::vector<x_type> preOrderVec;
if (rootptr != nullptr)
{
std::vector<x_type> temp;
preOrderVec.push_back(rootptr->value);
if (rootptr->leftChild != nullptr)
{
temp = preOrderWalk(rootptr->leftChild); //mästarns notering
preOrderVec.insert(preOrderVec.end(), temp.begin(), temp.end());
}
if (rootptr->rightChild != nullptr)
{
temp = preOrderWalk(rootptr->rightChild);
preOrderVec.insert(preOrderVec.end(), temp.begin(), temp.end());
}
}
return preOrderVec;
}
template <typename x_type>
std::vector<x_type> AVLTree<x_type>::inOrderWalk(){
return inOrderWalk(this->rootptr);
}
template <typename x_type>
std::vector<x_type> AVLTree<x_type>::inOrderWalk(bstNode* rootptr)
{
std::vector<x_type> inOrderVec;
if (rootptr != nullptr)
{
std::vector<x_type> temp;
if (rootptr->leftChild != nullptr)
{
temp = inOrderWalk(rootptr->leftChild); //mästarns notering
inOrderVec.insert(inOrderVec.end(), temp.begin(), temp.end());
}
inOrderVec.push_back(rootptr->value);
if (rootptr->rightChild != nullptr)
{
temp = inOrderWalk(rootptr->rightChild);
inOrderVec.insert(inOrderVec.end(), temp.begin(), temp.end());
}
}
return inOrderVec;
}
template <typename x_type>
std::vector<x_type> AVLTree<x_type>::postOrderWalk(){
return postOrderWalk(this->rootptr);
}
template <typename x_type>
std::vector<x_type> AVLTree<x_type>::postOrderWalk(bstNode* rootptr)
{
std::vector<x_type> postOrderVec;
if (rootptr != nullptr)
{
std::vector<x_type> temp;
if (rootptr->leftChild != nullptr)
{
temp = postOrderWalk(rootptr->leftChild); //mästarns notering
postOrderVec.insert(postOrderVec.end(), temp.begin(), temp.end());
}
if (rootptr->rightChild != nullptr)
{
temp = postOrderWalk(rootptr->rightChild);
postOrderVec.insert(postOrderVec.end(), temp.begin(), temp.end());
}
postOrderVec.push_back(rootptr->value);
}
return postOrderVec;
}
template <typename x_type>
x_type AVLTree<x_type>::getMin()
{
return (getMin(this->rootptr));
}
template <typename x_type>
x_type AVLTree<x_type>::getMin(bstNode* rootptr)
{
if (rootptr == nullptr) //empty tree
{
std::cout << "No minimum because the tree is empty" << std::endl;
}
else if(rootptr->leftChild == nullptr) //the node that has no leftChild must be the last we want to search
{
return rootptr->value;
}
return getMin(rootptr->leftChild);
}
template <typename x_type>
x_type AVLTree<x_type>::getMax()
{
return getMax(this->rootptr);
}
template <typename x_type>
x_type AVLTree<x_type>::getMax(bstNode* rootptr)
{
if (rootptr == nullptr) // empty tree
{
std::cout << "No maximum because the tree is empty" << std::endl;
}
else if(rootptr->rightChild == nullptr) //the node that has no rightChild must be the last we want to search
{
return rootptr->value;
}
return getMax(rootptr->rightChild);
}
template <typename x_type>
x_type AVLTree<x_type>::maxVal(x_type a, x_type b)
{
if (a > b) return a;
else return b;
}
template <typename x_type>
size_t AVLTree<x_type>::getTreeHeight()
{
return getTreeHeight(this->rootptr);
}
template <typename x_type>
size_t AVLTree<x_type>::getTreeHeight(bstNode* rootptr)
{
int height;
int leftHeight;
int rightHeight;
if (rootptr == nullptr) return -1;
leftHeight = getTreeHeight(rootptr->leftChild);
rightHeight = getTreeHeight(rootptr->rightChild);
height = (maxVal(leftHeight, rightHeight));
height += 1;
//static_cast<size_t>(height);
return height;
}
int main()
{
AVLTree<int>* avlTreeobject = new AVLTree<int>();
avlTreeobject->insert(7);
avlTreeobject->insert(6);
avlTreeobject->insert(5);
std::cout << "\n actual root: " << (avlTreeobject->get_rootptr()->value);
std::cout << "\n actual root->leftchild: " << (avlTreeobject->get_rootptr()->leftChild->value);
std::cout << "\n actual root->rightchild: " << (avlTreeobject->get_rootptr()->rightChild->value);
std::cin.get();
std::getchar();
return 0;
}
I'm not sure but I think that the problem is that I'm sending in the wrong node to the function, therefore it crashes because it assumes the node im sending in will have a child but it wont and therefore it tries to access a nullptr. I don't know how to fix this though
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
I'm trying to create a binary search tree by keeping the path: each node has a link to its parent. Below is the classic binary search. How do I change it to be able to solve my problem?
I tried adding the "father" pointer to the struct but I have no problems understanding how and when to save it. I am new to this language so be patient. thank you so much
#include <iostream>
template <class T>
class BinaryTree
{
struct node {
T value;
struct node* right;
struct node* left;
};
public:
BinaryTree();
~BinaryTree();
void add(T val);
void printPreOrder();
void printInOrder();
void printPostOrder();
int size();
bool lookup(T val);
private:
struct node* root;
int treeSize;
void add(struct node** node, T val);
bool lookup(struct node* node, T val);
void printPreOrder(struct node* node);
void printInOrder(struct node* node);
void printPostOrder(struct node* node);
void deleteTree(struct node* node);
};
template <class T>
BinaryTree<T>::BinaryTree() {
this->root = NULL;
this->treeSize = 0;
}
template <class T>
BinaryTree<T>::~BinaryTree() {
deleteTree(this->root);
}
template <class T>
int BinaryTree<T>::size() {
return this->treeSize;
}
template <class T>
void BinaryTree<T>::add(T val) {
add(&(this->root), val);
}
template <class T>
void BinaryTree<T>::add(struct node** node, T val) {
if (*node == NULL) {
struct node* tmp = new struct node;
tmp->value = val;
tmp->left = NULL;
tmp->right = NULL;
*node = tmp;
this->treeSize++;
}
else {
if (val > (*node)->value) {
add(&(*node)->right, val);
}
else {
add(&(*node)->left, val);
}
}
}
template <class T>
void BinaryTree<T>::printInOrder() {
printInOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printInOrder(struct node* node) {
if (node != NULL) {
printInOrder(node->left);
std::cout << node->value << ", ";
printInOrder(node->right);
}
}
template <class T>
void BinaryTree<T>::printPreOrder() {
printPreOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printPreOrder(struct node* node) {
if (node != NULL) {
std::cout << node->value << ", ";
printInOrder(node->left);
printInOrder(node->right);
}
}
template <class T>
void BinaryTree<T>::printPostOrder() {
printPostOrder(this->root);
std::cout << std::endl;
}
template <class T>
void BinaryTree<T>::printPostOrder(struct node* node) {
if (node != NULL) {
printInOrder(node->left);
printInOrder(node->right);
std::cout << node->value << ", ";
}
}
template <class T>
void BinaryTree<T>::deleteTree(struct node* node) {
if (node != NULL) {
deleteTree(node->left);
deleteTree(node->right);
delete node;
}
}
template <class T>
bool BinaryTree<T>::lookup(T val) {
return lookup(this->root, val);
}
template <class T>
bool BinaryTree<T>::lookup(struct node* node, T val) {
if (node == NULL) {
return false;
}
else {
if (val == node->value) {
return true;
}
if (val > node->value) {
return lookup(node->right, val);
}
else {
return lookup(node->left, val);
}
}
}
I will give you the recursive solution since it is the natural way to implement it:
First it would be a good idea to define a constructor in your struct like so:
node(T value, node* left = nullptr, node* right = nullptr){
this->value = value;
this->left = left;
this->right = right;
}
Take out the struct in the struct node* root.
void insert(T value){
Node* temp = root;
insert(value, root);
}
//helper function
void insert(T value, Node* root){
if(root->left == nullptr && root->right == nullptr){
if(root->value < value){
root->left = new Node(value);
}
else{
root->right = new Node(value);
}
return;
}
if(value < root->value)insert(value, root->left);
else{
insert(value, root->right);
}
}
Not sure where you got your code it does not look correct....
I don't understand the need for pointer to pointer to struct node in your code. Pointer to struct node would suffice. As far as your question goes, you can pass the parent of current node as a third parameter in the method add. Initially it will be null. Now incase you have to go down to the child of the current node, then the current node becomes it's parent. When you have to allocate memory for value val, set the it's parent there.
template <class T>
void BinaryTree<T>::add(struct node** node, T val, struct node* parent = nullptr) {
if (*node == NULL) {
struct node* tmp = new struct node;
tmp->value = val;
tmp->left = NULL;
tmp->right = NULL;
temp->parent = parent;
*node = tmp;
this->treeSize++;
}
else {
if (val > (*node)->value) {
add(&(*node)->right, val, *node);
}
else {
add(&(*node)->left, val, *node;
}
}
}
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 have problem to convert infix to postfix this is my code it takes the characterinfix input but does not show any postfix output Please tell me whats the problem.I have been trying to solve it but i found no problem in it i will be thanks full you if someone find the problem.And the other thing is how may i add {} and [] this brackets too ?
#include <iostream>
#include<string.h>
using namespace std;
template <class T>
class Node
{
public:
T info;
Node *ptrnext;
Node *ptrprevious;
Node()
{
info = 0;
ptrnext = 0;
ptrprevious = 0;
}
Node(T e, Node *n, Node *p)
{
info = e;
ptrnext = n;
ptrprevious = p;
}
};
template <class T>
class DLinkedList
{
private:
Node<T> *head;
Node<T> *tail;
public:
DLinkedList()
{
head = 0;
tail = 0;
}
bool isEmpty();
void addToHead(T e);
void addToTail(T e);
void deleteFromHead();
void deleteFromTail();
void display();
T getHead();
int numofNodes();
~DLinkedList(){
if(!isEmpty())
{
while(head!=0){
if(head==tail)
{
delete head;
head=0;
tail=0;
}
else{
Node<T> *ptrtemp=head;
head=head->ptrnext;
head->ptrprevious=NULL;
delete ptrtemp;
}
}
}
}
};
template <class T>
bool DLinkedList<T>::isEmpty()
{
if (head == 0)
{
return true;
}
else
{
return false;
}
}
template <class T>
void DLinkedList<T>::addToHead(T e)
{
Node<T> *ptrnode = new Node<T>(e,0,0);
if(isEmpty())
{
head = ptrnode;
tail = ptrnode;
}
else
{
ptrnode->ptrnext = head;
head->ptrprevious = ptrnode;
ptrnode->ptrprevious = 0;
head = ptrnode;
}
}
template <class T>
void DLinkedList<T>::addToTail(T e)
{
Node<T> *ptrnode = new Node<T>(e,0,0);
if(isEmpty())
{
head = ptrnode;
tail = ptrnode;
}
else
{
tail->ptrnext = ptrnode;
ptrnode->ptrprevious = tail;
ptrnode->ptrnext = 0;
tail = ptrnode;
}
}
template <class T>
void DLinkedList<T>::deleteFromHead()
{
if(!isEmpty())
{
if(head == tail)
{
delete head;
head = 0;
tail = 0;
}
else
{
Node<T> *ptrtemp = head;
head = head->ptrnext;
head->ptrprevious = 0;
delete ptrtemp;
}
}
}
template <class T>
void DLinkedList<T>::deleteFromTail()
{
if(!isEmpty())
{
if(head == tail)
{
delete tail;
head = 0;
tail = 0;
}
else
{
Node<T> *ptrtemp = tail;
tail = tail->ptrprevious;
tail->ptrnext = 0;
delete ptrtemp;
}
}
}
template <class T>
void DLinkedList<T>::display()
{
if(!isEmpty())
{
Node<T> *ptrtemp = head;
while(ptrtemp->ptrnext != 0)
{
cout<<ptrtemp->info;
ptrtemp = ptrtemp->ptrnext;
}
cout<<ptrtemp->info<<endl;
}
}
template <class T>
T DLinkedList<T>::getHead()
{
if(isEmpty())
{
return 0;
}
else
{
return head->info;
}
}
template <class T>
int DLinkedList<T>::numofNodes()
{
if(isEmpty())
{
return 0;
}
else
{
int count = 0;
Node<T> *ptrtemp = head;
while(ptrtemp->ptrnext != 0)
{
count++;
ptrtemp = ptrtemp->ptrnext;
}
count++;
return count;
}
}
template <class T>
class Stack:public DLinkedList<T>
{
private:
int maxStackSize;
public:
Stack()
{
maxStackSize = 10;
}
bool isEmpty();
bool isFull();
void Push(T e);
T Pop();
void display();
T topvalue();
};
template <class T>
bool Stack<T>::isEmpty()
{
bool r= DLinkedList<T>::isEmpty();
return r;
}
template <class T>
bool Stack<T>::isFull()
{
int totalNodes = DLinkedList<T>::numofNodes();
if(totalNodes == maxStackSize)
{
return true;
}
else
{
return false;
}
}
template <class T>
void Stack<T>::Push(T e)
{
if( isFull() )
{
cout<<"Stack Full "<<endl;
}
else
{
DLinkedList<T>::addToHead(e);
}
}
template <class T>
T Stack<T>::Pop()
{
if(isEmpty())
{
return 0;
}
else
{
T n = DLinkedList<T>::getHead();
DLinkedList<T>::deleteFromHead();
return n;
}
}
template <class T>
void Stack<T>::display()
{
if( isEmpty() )
{
cout<<"Stack Empty!!"<<endl;
}
else
{
DLinkedList<T>::display();
}
}
template<class T>
T Stack<T>::topvalue()
{
T temp;
temp=DLinkedList<T>::getHead();
return temp;
}
int main()
{
Stack<char> obj;
char input[20];
cout<<"Enter Values \n";
cin>>input;
int size= strlen(input);
for(int i=0; i <size ; i++)
{
//======= For + or - Operators=========
if(input[i]=='+' || input[i]=='-')
{
if(obj.topvalue()=='+' || obj.topvalue()=='-')
{ //======= CASE-1=======
cout<<obj.Pop();
obj.Push(input[i]);
}
else if(obj.topvalue()=='*' || obj.topvalue()=='/')
{
//======= CASE-2=========
cout<<obj.Pop();
if(obj.topvalue()=='*' || obj.topvalue()=='/')
{
cout<<obj.Pop();
}
obj.Push(input[i]);
}
else if(obj.topvalue()=='(')
{
//======= CASE-3=========
obj.Push(input[i]);
}
else if(obj.isEmpty())
{
//======= CASE-4=========
obj.Push(input[i]);
}
}
// ++++++++++ FOR * and / Operators ++++++++
else if(obj.topvalue()=='*' || obj.topvalue()=='/')
{
if(obj.topvalue()=='+' || obj.topvalue()=='-')
{
//======= CASE-1=========
cout<<obj.Pop();
obj.Push(input[i]);
}
else if(obj.isEmpty())
{
//======= CASE-2=========
obj.Push(input[i]);
}
else if(obj.topvalue()=='(')
{
//======= CASE-3=========
obj.Push(input[i]);
}
else
{
//======= CASE-4=========
obj.Push(input[i]);
}
}
// ++++++++++ Opening bracket ++++++++
else if (obj.topvalue()=='(')
{
obj.Push(input[i]);
}
// ++++++++++ Closing Bracket ++++++++
else if(input[i] != ')')
{
while(obj.topvalue() != '(')
{
cout<<obj.Pop();
}
obj.Pop();
}
// ++++++++++ Operands ++++++++
else
{
cout<<input[i];
}
}
// ++++++++++ Print All values from the Stack and empty it++++++++
while(!obj.isEmpty())
{
cout<<obj.Pop();
}
return 0;
}
>
You have made mistake in following line:
else if (input[i] != ')')
due to which the program is going into infinite loop.
It needs to be:
else if (input[i] == ')')
Please read the comments below
Here is the specific error:
Error 2 error LNK2019: unresolved external symbol "void __cdecl totalPolynomial(class LinkedList *,class LinkedList *,class LinkedList *)" (?totalPolynomial##YAXPAV?$LinkedList#VTerm####00#Z) referenced in function _main
Warning 1 warning C4805: '==' : unsafe mix of type 'unsigned int' and type 'bool' in operation 38
I think the problem resides in sumPolynomial in functions.cpp/.h Specifically with it's declaration/implementation.
header.h
#include <iostream>
#include <string>
#include <sstream>
#include <stdlib.h>
using namespace std;
#include "linkedList.h"
#include "term.h"
void loadPolynomial(string expression, LinkedList<Term> *theList);
void totalPolynomial(LinkedList<Term> *x, LinkedList<Term> *y, LinkedList<Term> *sum);
functions.cpp
#include "header.h"
void loadPolynomial(string expression, LinkedList<Term> *theList)
{
Term tempPolynomial;
string varDelimiter = "x";
string posDelimiter = "+";
string negDelimiter = "-";
string token = "";
double coefficient;
double exponent;
/*bool isNeg;*/
bool removedCoefficient = false;
while(expression.length() > 0)
{
/*isNeg = false;*/
coefficient = 1.0;
exponent = 1.0;
removedCoefficient = false;
if(expression.substr(0, 1) == "+")
{
expression.erase(0, 1);
}
/*else if(expression.substr(0, 1) == "-")
{
isNeg = true;
expression.erase(0, 1);
}*/
if( expression.length() > 1 && expression.find(varDelimiter) == true)
{
//Get the coefficient
token = expression.substr(0, expression.find(varDelimiter));
//Remove the coefficient and variable from the string leaving only the exponent
expression.erase(0, expression.find(varDelimiter) + varDelimiter.length());
//Convert and put token's coeficient into a double
coefficient = atof(token.c_str());
/*if(isNeg == true)
{
coefficient = coefficient * -1;
}*/
//Put the coefficient value into the tempPolynomial
tempPolynomial.setCoefficient(coefficient);
removedCoefficient = true;
}
if(expression.find(posDelimiter) > 0 && expression.length() > 0 && removedCoefficient == true)
{
//Get the exponent
token = expression.substr(0, expression.find(posDelimiter));
//Remove the exponent but leave the +
expression.erase(0, expression.find(posDelimiter) + posDelimiter.length());
//Convert and put token's coeficient into a double
exponent = atof(token.c_str());
//Put the exponent value into the tempPolynomial
tempPolynomial.setExponent(exponent);
}
if(removedCoefficient == false)
{
//Get the trailing number
token = expression.substr(0);
coefficient = atof(token.c_str());
//Set it as the coefficient
tempPolynomial.setCoefficient(coefficient);
//Set the exponent as 0 so we know it doesn't include a variable
tempPolynomial.setExponent(0.0);
//Remove it from the string
expression.erase(0, token.length());
}
//Intert the first term into the linked list
theList->insert(tempPolynomial);
}
}
void sumPolynomial(LinkedList<Term> *x, LinkedList<Term> *y, LinkedList<Term> *sum)
{
LinkedList<Term> *tempNodeX;
LinkedList<Term> *tempNodeY;
Term tempTermX;
Term tempTermY;
Term newTerm;
tempNodeX = x->getNext();
tempNodeY = y->getNext();
while(tempNodeX != NULL)
{
tempTermX = tempNodeX->getData();
while(tempNodeY !=NULL)
{
tempTermY = tempNodeY->getData();
if(tempTermX.getExponent() == tempTermY.getExponent())
{
newTerm.setCoefficient(tempTermX.getCoefficient() + tempTermY.getCoefficient());
newTerm.setExponent(tempTermY.getExponent());
sum->insert(newTerm);
}
tempNodeX = tempNodeY->getNext();
}
tempNodeX = tempNodeX->getNext();
}
}
term.h
#ifndef TERM_H
#define TERM_H
#include<iostream>
using namespace std;
class Term
{
private:
double mCoefficient;
double mExponent;
public:
Term();
//Term(double coefficient);
//Term(double exponent);
Term(double coefficient, double exponent);
~Term();
double getCoefficient();
double getExponent();
void setCoefficient(double coefficient);
void setExponent(double exponent);
friend ostream& operator<<(ostream &output, Term object);
bool operator==(Term right);
//friend bool operator==(Term left, Term right);
bool operator!=(Term right);
//friend bool operator!=(Term left, Term right);
bool operator>(Term right);
//friend bool operator>(Term left, Term right);
bool operator<(Term right);
//friend bool operator<(Term left, Term right);
};
#endif
term.cpp
#include "term.h"
Term::Term()
{
mCoefficient = 1;
mExponent = 1;
}
//
//Term::Term(double coefficient)
//{
// mCoefficient = coefficient;
// mExponent = 1.0;
//}
//
//
//Term::Term(double exponent)
//{
// mCoefficient = 1.0;
// mExponent = exponent;
//}
Term::Term(double coefficient, double exponent)
{
mCoefficient = coefficient;
mExponent = exponent;
}
Term::~Term(){}
double Term::getCoefficient()
{
return mCoefficient;
}
double Term::getExponent()
{
return mExponent;
}
void Term::setCoefficient(double coefficient)
{
mCoefficient = coefficient;
}
void Term::setExponent(double exponent)
{
mExponent = exponent;
}
ostream& operator<<(ostream &output, Term object)
{
if(object.mExponent > 0)
{
output << object.mCoefficient << "x" << object.mExponent;
}
else
{
output << object.mCoefficient;
}
return output;
}
bool Term::operator==(Term right)
{
if(mExponent == right.mExponent && mCoefficient == right.mCoefficient)
{
return true;
}
else
{
return false;
}
}
bool Term::operator!=(Term right)
{
if(mExponent != right.mExponent)
{
return true;
}
else if(mCoefficient != right.mCoefficient)
{
return true;
}
else
{
return false;
}
}
bool Term::operator>(Term right)
{
if(mExponent > right.mExponent)
{
return true;
}
else if(mExponent == right.mExponent && mCoefficient > right.mCoefficient)
{
return true;
}
else
{
return false;
}
}
bool Term::operator<(Term right)
{
if(mExponent < right.mExponent)
{
return true;
}
else if(mExponent == right.mExponent && mCoefficient < right.mCoefficient)
{
return true;
}
else
{
return false;
}
}
linkedList.h
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#include <iostream>
#include <fstream>
using namespace std;
template <class T>
class LinkedList
{
private:
T mData;
LinkedList<T> *mNext;
public:
LinkedList();
LinkedList(T data);
~LinkedList();
T getData();
LinkedList<T> *getNext();
void setData(T data);
void display();
void insert(T data);
bool isExist(T data);
void remove(T data);
friend ostream& operator<<(ostream &output, LinkedList<T> object);
bool operator==(T right);
friend bool operator==(T left, LinkedList<T> right);
bool operator!=(T right);
friend bool operator!=(T left, LinkedList<T> right);
bool operator>(T right);
friend bool operator>(T left, LinkedList<T> right);
bool operator<(T right);
friend bool operator<(T left, LinkedList<T> right);
};
template <class T>
LinkedList<T>::LinkedList()
{
mNext = NULL;
mData = T();
}
template <class T>
LinkedList<T>::LinkedList(T data)
{
mNext = NULL;
mData = data;
}
template <class T>
LinkedList<T>::~LinkedList()
{
LinkedList<T> *tempNode;
tempNode = mNext;
while(tempNode != NULL)
{
mNext = tempNode->mNext;
tempNode->mNext = NULL;
delete tempNode;
tempNode = mNext;
}
}
template <class T>
T LinkedList<T>::getData()
{
return mData;
}
template <class T>
LinkedList<T> *LinkedList<T>::getNext()
{
return mNext;
}
template <class T>
void LinkedList<T>::setData(T data)
{
mData = data;
}
template <class T>
void LinkedList<T>::display()
{
LinkedList<T> *tempNode;
tempNode = mNext;
while(tempNode != NULL)
{
cout << tempNode->mData << endl;
tempNode = tempNode->mNext;
}
}
template <class T>
void LinkedList<T>::insert(T data)
{
LinkedList<T> *previousNode;
LinkedList<T> *tempNode;
LinkedList<T> *newNode;
newNode = new LinkedList(data);
if(mNext == NULL)
{
mNext = newNode;
}
else
{
previousNode = mNext;
tempNode = mNext;
while(tempNode != NULL && tempNode->mData > data)
{
previousNode = tempNode;
tempNode = tempNode->mNext;
}
if(tempNode == mNext)
{
newNode->mNext = mNext;
mNext = newNode;
}
else
{
previousNode->mNext = newNode;
newNode->mNext = tempNode;
}
}
}
template <class T>
bool LinkedList<T>::isExist(T data)
{
LinkedList<T> *tempNode;
bool exist = false;
tempNode = mNext;
while(tempNode != NULL)
{
if(tempNode->mData == data)
{
exist = true;
break;
}
tempNode = tempNode->mNext;
}
return exist;
}
template <class T>
void LinkedList<T>::remove(T data)
{
LinkedList<T> *tempNode;
LinkedList<T> *previousNode;
if(isExist(data) == false)
{
return;
}
tempNode = mNext;
previousNode = mNext;
while(tempNode->mData != data)
{
previousNode = tempNode;
tempNode = tempNode->mNext;
}
if(tempNode == mNext)
{
mNext = tempNode->mNext;
tempNode->mNext = NULL;
}
else
{
if(tempNode->mNext == NULL)
{
previousNode->mNext = NULL;
}
else
{
previousNode->mNext = tempNode->mNext;
tempNode->mNext = NULL;
}
}
delete tempNode;
}
template <class T>
ostream& operator<<(ostream &output, LinkedList<T> object)
{
output << object.mData;
return output;
}
template <class T>
bool LinkedList<T>::operator==(T right)
{
return mData == right;
}
template <class T>
bool operator==(T left, LinkedList<T> right)
{
return left == right.mData;
}
template <class T>
bool LinkedList<T>::operator!=(T right)
{
return mData != right;
}
template <class T>
bool operator!=(T left, LinkedList<T> right)
{
return left != right.mData;
}
template <class T>
bool LinkedList<T>::operator>(T right)
{
return mData > right;
}
template <class T>
bool operator>(T left, LinkedList<T> right)
{
return left > right.mData;
}
template <class T>
bool LinkedList<T>::operator<(T right)
{
return mData < right;
}
template <class T>
bool operator<(T left, LinkedList<T> right)
{
return left < right.mData;
}
#endif
Here is the revised loop that now works:
while(tempNodeX != NULL)
{
tempTermX = tempNodeX->getData();
while(tempNodeY != NULL)
{
tempTermY = tempNodeY->getData();
if(tempTermX.getExponent() == tempTermY.getExponent())
{
newTerm.setCoefficient(tempTermX.getCoefficient() + tempTermY.getCoefficient());
newTerm.setExponent(tempTermY.getExponent());
//cout << tempTermX << " " << tempTermY << " " << newTerm << endl;
sum->insert(newTerm);
tempNodeY = y->getNext();
tempNodeY->remove(tempTermY);
break;
}
tempNodeY = tempNodeY->getNext();
}
tempNodeX = tempNodeX->getNext();
tempNodeY = y->getNext();
}