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] == ')')
Related
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
this is my current avltree implementation, avltree.h:
#pragma once
#include <math.h>
#include <algorithm>
#include <iostream>
namespace avltree {
template <class T>
struct node {
static node * null_node;
node *left = null_node;
node *right = null_node;
node *parent = null_node;
int height = 0;
T value;
node(T value) :value(value) {}
node(T value, int height) :height(height), value(value) {}
};
template <class T>
node<T>* node<T>::null_node = new node(0, -1);
template <class T>
struct avltree {
public:
node<T> *root;
avltree(T value);
node<T> *insert(T value);
void print(void);
void print_with_height(void);
private:
node<T> *insert(T value, node<T> *x);
node<T> *left_rotate(node<T> *x);
node<T> *right_rotate(node<T> *x);
void retrace(node<T> *n);
void update_root();
void print(node<T> *n);
void print(node<T> *n, int depth);
void update_height(node<T> *n);
};
template <class T>
avltree<T>::avltree(T value) :root(new node<T>(value)) { }
template <class T>
node<T> *avltree<T>::insert(T value) {
auto n = insert(value, root);
update_root();
return n;
}
template <class T>
void avltree<T>::retrace(node<T> *n) {
while (n != node<T>::null_node) {
update_height(n);
if (n->left->height - n->right->height > 1) {
if (n->left->left->height >= n->left->right->height) {
right_rotate(n);
}
else {
left_rotate(n);
right_rotate(n);
}
}
else
if (n->right->height - n->left->height > 1) {
if (n->right->right->height >= n->right->left->height) {
left_rotate(n);
}
else {
right_rotate(n);
left_rotate(n);
}
}
n = n->parent;
}
}
template <class T>
node<T> *avltree<T>::insert(T value, node<T> *n) {
if (n->value > value) {
if (n->left != node<T>::null_node) {
n->left->height++;
insert(value, n->left);
}
else {
auto new_node = new node<T>(value);
n->left = new_node;
new_node->parent = n;
retrace(n);
return new_node;
}
}
if (n->value < value) {
if (n->right != node<T>::null_node) {
n->right->height++;
insert(value, n->right);
}
else {
auto new_node = new node<T>(value);
n->right = new_node;
new_node->parent = n;
retrace(n);
return new_node;
}
}
update_height(n);
return n;
}
template <class T>
node<T> *avltree<T>::left_rotate(node<T> *x) {
node<T> *y = x->right;
if (y == node<T>::null_node) {
return node<T>::null_node;
}
y->parent = x->parent;
if (x->parent->right == x) {
x->parent->right = y;
}
else {
x->parent->left = y;
}
y->left = x;
x->parent = y;
x->right = y->left;
x->right->parent = x;
update_height(x);
update_height(y);
return x;
}
template <class T>
node<T> *avltree<T>::right_rotate(node<T> *x) {
node<T> *y = x->left;
if (y == node<T>::null_node) {
return node<T>::null_node;
}
y->parent = x->parent;
if (x->parent->right == x) {
x->parent->right = y;
}
else {
x->parent->left = y;
}
y->right = x;
x->parent = y;
x->left = y->right;
x->left->parent = x;
update_height(x);
update_height(y);
return x;
}
template <class T>
void avltree<T>::update_root() {
auto n = root, last = root;
while (n != node<T>::null_node) {
last = n;
n = n->parent;
}
root = last;
}
template <class T>
void avltree<T>::print(void) {
print(root);
cout << endl;
}
template <class T>
void avltree<T>::print(node<T> *n) {
if (n->left != node<T>::null_node) {
print(n->left);
}
cout << n->value << " ";
if (n->right != node<T>::null_node) {
print(n->right);
}
}
template <class T>
void avltree<T>::print(node<T> *n, int height) {
if (n->left != node<T>::null_node) {
print(n->left, height);
}
if (n->height == height) {
std::cout << n->value << ", ";
}
if (n->right != node<T>::null_node) {
print(n->right, height);
}
}
template <class T>
void avltree<T>::print_with_height(void) {
int height = root->height;
for (int height = root->height; height >= 0; height--) {
std::cout << "height = " << height << "\t:";
print(root, height);
std::cout << std::endl;
}
std::cout << std::endl;
}
template <class T>
void avltree<T>::update_height(node<T> *n) {
n->height = std::max(n->left->height, n->right->height) + 1;
}
}
And the following is main file:
#include "stdafx.h"
#include "avltree.h"
int main()
{
avltree::avltree<int> tree(1);
for (int i = 2; i < 128; i++) {
tree.insert(i);
}
tree.print_with_height();
return 0;
}
The problem with above code is that at iteration 124 it will generate an infinite loop inside retrace call in insert. Basically, the nodes will keep being rotated in such a way that root node cannot be reached (resulting in an infinite loop). I have checked the trivial examples (for a few nodes) and they work. Everything for a run is provided, I would appreciate if someone with experience in avltrees could take their time and run this program, perhaps finding out what goes wrong inside retrace/rotations.
Getting an infinite loop like that indicates a likely problem with your rotate functions. A quick look at left_rotate shows
y->left = x;
x->parent = y;
x->right = y->left;
What is y->left in that last assignment? x, so what you're really is x->right = x. This is clearly a problem that needs to be fixed.
A similar problem exists in right_rotate.
I want to call this function in main() but problem is that what parameter I should pass in it while it receives Node type argument
In Simple I just wanna see the height of my tree. So please help me, remove the error which I face during the function call of height it needs a Node type parameter and I have no idea what should I pass. Here is the whole code
#include <iostream>
using namespace std;
// Binary Search Tree
//
class Node
{
public:
int data;
Node *left,*right;
Node(Node *l=NULL ,int d=0, Node *r=NULL)
{
left=l;
data=d;
right=r;
}
};
// Binary Search Tree
class Tree
{
Node *root;
public :
Tree()
{
root=NULL;
}
bool isEmpty()
{
if(root==NULL)
return true;
else
return false;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// insert funcation
/////////////////////////////////////////////////////////////////////////////////////////////////
void insert(int val)
{
if(isEmpty())
{
root=new Node(NULL,val,NULL);
}
else if(val < root->data && root->left==NULL)
{
Node *p=new Node(NULL ,val,NULL);
root->left=p;
}
else if(val > root->data && root->right==NULL)
{
Node *p=new Node (NULL ,val,NULL);
root->right=p;
}
else if(val < root->data)
insert(val ,root->left);
else
insert(val ,root->right);
}
////////////////////////////////////////
void insert(int val,Node *n)
{
if(val>n->data && n->right==NULL)
{
Node *p=new Node(NULL,val,NULL);
n->right=p;
}
else if(val > n->data)
insert(val,n->right);
else if(val <n->data && n->left==NULL)
{
Node *p=new Node(NULL,val,NULL);
n->left=p;
}
else
insert(val,n->left);
}
//////////////////////////////////////////////////////////////////////////////////////
// pre Order all data display
//////////////////////////////////////////////////////////////////////////////////////
void preOrder(void)
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
preOrder(root);
}
void preOrder(Node *n)
{
if(n!=NULL)
{
cout<<n->data<<endl;
preOrder(n->left);
preOrder(n->right);
}
}
//////////////////////////////////////////////////////////////////////////////////////
// in fix Order all data display
//////////////////////////////////////////////////////////////////////////////////////
void inOrder()
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
inOrder(root);
}
void inOrder(Node *n)
{
if(n!=NULL)
{
inOrder(n->left);
cout<<n->data<<endl;
inOrder(n->right);
}
}
//////////////////////////////////////////////////////////////////////////////////////
// post Order all data display
//////////////////////////////////////////////////////////////////////////////////////
void posOrder()
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
posOrder(root);
}
void posOrder(Node *n)
{
if(n!=NULL)
{
posOrder(n->left);
posOrder(n->right);
cout<<n->data<<endl;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Search funcation
/////////////////////////////////////////////////////////////////////////////////////////////////
void search(int val)
{
if(isEmpty())
cout<<"Tree is Empty\n";
else
search(val,root);
}
void search(int v,Node *p)
{
if(v==p->data)
cout<<"val : "<<p->data<<endl;
else if(v < p->data && p->left!=NULL)
search(v,p->left);
else if(v>p->data && p->right!=NULL)
search(v,p->right);
else
cout<<"Data Not Found \n";
}
Node *l;
int deleteKey(int val)
{
if(isEmpty())
cout<<"Tree is Empty\n";
else if(root->data==val &&(root->left==NULL&&root->right==NULL))
{
int temp=root->data;
delete root;
return temp;
}
else
deleteKey(val,root);
}
int deleteKey(int v,Node *p)
{
if(v == p->data)
{
if(p->left==NULL && p->right==NULL)
{
if(l->right==p)
{
int temp=p->data;
delete p;
l->right=NULL;
return temp;
}
else
{
int temp=p->data;
delete p;
l->left=NULL;
return temp;
}
}
else if(p->right!=NULL)
{
int temp=p->data;
deleteKey(p,p->right);
return temp;
}
else
{
int temp=p->data;
cout<<"Left : "<<p->data<<endl;
deleteKey(p,p->left,v);
return temp;
}
}
else if(v < p->data && p->left!=NULL)
{
l=p;
deleteKey(v,p->left);
}
else if(v>p->data &&p->right!=NULL)
{
l=p;
deleteKey(v,p->right);
}
else
cout<<"Data Not Found ----\n";
}
int deleteKey(Node *find ,Node *next)
{
if( next->left == NULL && next->right != NULL )
{
find->data = next->data;
deleteKey(find->right , next->right);
}
else if( next->left == NULL&& next->right==NULL)
{
find->data = next->data;
delete next;
find->right=NULL;
}
else
{
Node *q;
while(next->left!=NULL)
{
q=next;
next=next->left;
}
find->data=next->data;
delete next;
q->left=NULL;
}
}
int deleteKey(Node* find,Node *next,int v)
{
if( next->right == NULL && next->left != NULL )
{
find->data = next->data;
deleteKey(find->left , next->left,v);
}
else if( next->right == NULL&& next->left==NULL)
{
find->data = next->data;
delete next;
find->left=NULL;
}
else
{
Node *q;
while(next->right!=NULL)
{
q=next;
next=next->right;
}
find->data=next->data;
delete next;
q->right=NULL;
}
}
~Tree()
{
dist();
}
void dist()
{
dist(root);
}
void dist(Node *n)
{
if(n!=NULL)
{
dist(n->left);
dist(n->right);
delete n;
}
}
int height(Node *root)
{
int h=0;
if (isEmpty())
{
cout<<"Tree is Empty\n";
}
else
{
int left_height=height(root->left);
int right_height=height(root->right);
h=1+max(left_height, right_height);
}
return h;
}
};
int main()
{
Tree obj;
obj.height();
}
Well you have to pass, root of your tree in this function, but the better approach will be if you make one more function without any parameter and make that function public and call your this private function from it by passing this->root;
Here you can see :
public:
int getHeight()
{
return height(this->root); //pass your Tree class root
}
and make that function private in class , for efficiency.
private:
int height(Node *root)
{
int h=0;
if (isEmpty())
{
cout<<"Tree is Empty\n";
}
else
{
int left_height=height(root->left);
int right_height=height(root->right);
h=1+max(left_height, right_height);
}
return h;
}
Another, approach is to make a getRoot() function in class and get Root of Tree class in main and pass to height function. But The first approach will be better.
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 only use function insert, remove and midorder.
#include<iostream>
template<class Elem>
class BinNode
{
public:
virtual Elem& getVal() = 0;
};
template<class Elem>
class BinNodePtr:public BinNode<Elem>
{
public:
Elem val;
BinNodePtr* lc;
BinNodePtr* rc;
BinNodePtr()
{
lc = rc = NULL;
}
~BinNodePtr()
{
delete lc;
delete rc;
}
Elem& getVal()
{
return this->val;
}
};
template<class Elem>
class BST
{
public:
BinNodePtr<Elem> *root;
int nodenum;
void midorder(BinNodePtr<Elem>* start);
public:
BST()
{
root = NULL;
nodenum = 0;
}
bool insert(BinNodePtr<Elem>*&ptr,const Elem &e);//
void remove(BinNodePtr<Elem>*&start,const Elem &e);//
BinNodePtr<Elem>* getRoot(){return root;}
};
template<class Elem>
void BST<Elem>::midorder(BinNodePtr<Elem> *start)
{
if(start == NULL) return;
midorder(start->lc);
printf("%d ",start->getVal());
midorder(start->rc);
}
template<class Elem>
bool BST<Elem>::insert(BinNodePtr<Elem>*&ptr,const Elem &e)
{
if(ptr == NULL)
{
ptr = new BinNodePtr<Elem>;
ptr->lc = NULL;
ptr->rc = NULL;
ptr->val = e;
return true;
}
else
{
if(ptr->val < e || ptr->val == e)
{
insert(ptr->rc,e);
}
else
{
insert(ptr->lc,e);
}
}
return false;
}
template<class Elem>
void BST<Elem>::remove(BinNodePtr<Elem>*&start,const Elem &e)
{
if(start == NULL)
return ;
if(start->val < e)
remove(start->rc,e);
else if(start->val > e)
remove(start->lc,e);
else
{
if(start->lc == NULL && start->rc == NULL)
{
delete start;
}
else if(start->lc == NULL)
{
BinNodePtr<Elem> *temp = start;
start = start->rc;
delete (temp);
}
else if(start->rc == NULL)
{
BinNodePtr<Elem> *temp = start;
start = start->lc;
delete temp;
}
else
{
BinNodePtr<Elem>* temp = start->rc;
while(temp->lc!= NULL)
{
temp = temp->lc;
}
start->val = temp->val;
remove(start->rc,temp->val);
}
}
}
int main()
{
BST<int> myBST;
(myBST.insert(myBST.root,10));
(myBST.insert(myBST.root,20));
(myBST.insert(myBST.root,5));
(myBST.insert(myBST.root,30));
myBST.midorder(myBST.getRoot());
myBST.remove(myBST.root,10);
myBST.midorder(myBST.getRoot());
system("pause");
return 0;
}
I have successfully inserted 10, 20, 5, 30 because I can "printf" them out, but the program breaks down when I use function remove. I debugged this and found that there is something wrong in function remove but I don't know how to fix it.