So, I want to take input from a text file, then do some operations in an AVL tree. I could implement insertion, yet I can't build a solution for deletion in my mind. Can you help me? Here is the code.
#include<iostream>
#include<cstdio>
#include<sstream>
#include<algorithm>
#include <fstream>
#include <stdlib.h>
#include <array>
#include <ctime>
using namespace std;
struct node
{
int data;
int height;
struct node *leftchild;
struct node *rightchild;
}*root;
class avlTree
{
public:
int height(node *);
int difference(node *);
node *rrtraversal(node *);
node *lltraversal(node *);
node *lrtraversal(node *);
node *rltraversal(node *);
node* balance(node *);
node* insert(node *, int );
void display(node *, int);
node *del(node *, int);
avlTree()
{
root = NULL;
}
};
int avlTree::height(node *temp)
{
int h = 0;
if (temp != NULL)
{
int l_height = height (temp->leftchild);
int r_height = height (temp->rightchild);
int max_height = max (l_height, r_height);
h = max_height + 1;
}
return h;
}
int avlTree::difference(node *temp)
{
int l_height = height (temp->leftchild);
int r_height = height (temp->rightchild);
int b_factor= l_height - r_height;
return b_factor;
}
node *avlTree::rrtraversal(node *parent)
{
node *temp;
temp = parent->rightchild;
parent->rightchild = temp->leftchild;
temp->leftchild = parent;
return temp;
}
node *avlTree::lltraversal(node *parent)
{
node *temp;
temp = parent->leftchild;
parent->leftchild = temp->rightchild;
temp->rightchild = parent;
return temp;
}
node *avlTree::lrtraversal(node *parent)
{
node *temp;
temp = parent->leftchild;
parent->leftchild = rrtraversal (temp);
return lltraversal (parent);
}
node *avlTree::rltraversal(node *parent)
{
node *temp;
temp = parent->rightchild;
parent->rightchild = lltraversal (temp);
return rrtraversal (parent);
}
node *avlTree::balance(node *temp)
{
int bal_factor = difference (temp);
if (bal_factor > 1)
{
if (difference (temp->leftchild) > 0)
temp = lltraversal (temp);
else
temp = lrtraversal (temp);
}
else if (bal_factor < -1)
{
if (difference (temp->rightchild) > 0)
temp = rltraversal (temp);
else
temp = rrtraversal (temp);
}
return temp;
}
node *avlTree::insert(node *root, int value)
{
if (root == NULL)
{
root = new node;
root->data = value;
root->leftchild = NULL;
root->rightchild = NULL;
return root;
}
else if (value < root->data)
{
root->leftchild = insert(root->leftchild, value);
root = balance (root);
}
else if (value >= root->data)
{
root->rightchild = insert(root->rightchild, value);
root = balance (root);
}
return root;
}
void avlTree::display(node *ptr, int level)
{
int i;
if (ptr!=NULL)
{
display(ptr->rightchild, level + 1);
printf("\n");
for (i = 0; i < level && ptr != root; i++)
cout<<" ";
cout<<ptr->data;
display(ptr->leftchild, level + 1);
}
}
node *avlTree::del(node *root, int x)
{
node *d;
if ( x < root->data){
del(root->leftchild,x);
}
else if (x > root->data){
del(root->rightchild,x);
}
else if ((root->leftchild == NULL) && (root->rightchild == NULL))
{
d=root;
free(d);
root=NULL;
}
else if (root->leftchild == NULL)
{
d=root;
free(d);
root= root->rightchild;
}
else if (root->rightchild == NULL)
{
d=root;
root=root->leftchild;
free(d);
}
return root;
}
int main()
{
ifstream myFile("file.txt");
int a = 0;
std::array<string,512> arrayTest;
int index = 0;
string content;
avlTree avl;
while (myFile >> content){
arrayTest[index] = content;
index++;
}
clock_t startTime = clock();
for(a = 0; a < arrayTest.size();a++){
if(arrayTest[a] == "i"){
root = avl.insert(root, std::stoi(arrayTest[a+1]));
}
}
avl.display(root,1);
clock_t endTime = clock();
clock_t clockTicksTaken = endTime - startTime;
double timeInSeconds = clockTicksTaken / (double) CLOCKS_PER_SEC;
cout << "\n\n" << timeInSeconds << " secs\n";
}
In file, the content is like this. i 1 i 2 i 3 i 4 i 5 d 3
If program sees i, it will do an insert operation. Likewise, if it sees d, it will do a delete operation.
Did you try free() function?
free(node);
Related
Well, i'm tried to build something like Binary Search Tree. And after some iterations i'm creating newnode and it has pointer which has already used. How to solve this problem, without classes. For example test,
9
1
7
5
21
22
27
25
20
10
Build it in reverse order (last is root, first cnt of vertex)
Here code:
#include <bits/stdc++.h>
using namespace std;
const int N = 3000;
int n;
int a[N];
struct node {
int v;
node *left, *right;
};
vector<int> ans;
node qwe;
void add(node *root, int elem) {
if (elem > root->v) {
if (root->right != NULL) {
add(root->right, elem);
} else {
node newnode{};
newnode.v = elem;
newnode.right = NULL;
newnode.left = NULL;
node *lsls;
lsls = &newnode;
root->right = lsls;
}
} else {
if (root->left != NULL) {
add(root->left, elem);
} else {
node newnode;
newnode.v = elem;
newnode.right = NULL;
newnode.left = NULL;
node *lsls;
lsls = &newnode;
root->left = lsls;
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
qwe.v = a[n - 1];
qwe.left = NULL;
qwe.right = NULL;
node *pointer;
pointer = &qwe;
for (int i = n - 2; i > -1; --i) {
add(pointer, a[i]);
}
pointer = &qwe;
return 0;
}
I am trying to insert 0 through 11 into avl and then delete 4, 5, 6 in that order. I am getting sigserv error while deleting 6 in rr_rotation function. This is the first time I am implementing avl and I am new to programming. Where am I going wrong? I added a few comments for my own understanding and to track where the error has occurred. Here is my code:
#include<bits/stdc++.h>
using namespace std;
#define pow2(n) (1 << (n))
struct avl_node {
int data;
//int size;
struct avl_node *left;
struct avl_node *right;
}*root;
class avlTree {
public:
int height(avl_node *);
int diff(avl_node *);
avl_node *rr_rotation(avl_node *);
avl_node *ll_rotation(avl_node *);
avl_node *lr_rotation(avl_node *);
avl_node *rl_rotation(avl_node *);
avl_node* balance(avl_node *);
avl_node* insert(avl_node *, int);
int getBalance(avl_node*);
int getSize(avl_node*);
avl_node* minValueNode(avl_node*);
avl_node* del(avl_node *, int);
void inorder(avl_node *);
void preorder(avl_node *);
int kthsmallest(avl_node*, int);
avlTree() {
root = NULL;
}
};
int avlTree::height(avl_node *temp) {
int h = 0;
if (temp != NULL) {
int l_height = height(temp->left);
int r_height = height(temp->right);
int max_height = max(l_height, r_height);
h = max_height + 1;
}
return h;
}
int avlTree::diff(avl_node *temp) {
int l_height = height(temp->left);
int r_height = height(temp->right);
int b_factor = l_height - r_height;
return b_factor;
}
avl_node *avlTree::rr_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside rr rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->right;
if(temp == NULL)
cout<<"yes null 2"<<endl;
//cout<<"parent->right "<<temp->data<<endl;
parent->right = temp->left;
temp->left = parent;
cout<<"temp->left->data "<<temp->left->data<<endl;
return temp;
}
avl_node *avlTree::ll_rotation(avl_node *parent) {
avl_node *temp;
//cout<<"inside ll rotation"<<endl;
//cout<<"parent = "<<parent->data<<endl;
temp = parent->left;
parent->left = temp->right;
temp->right = parent;
return temp;
}
avl_node *avlTree::lr_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside lr rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->left;
parent->left = rr_rotation(temp);
return ll_rotation(parent);
}
avl_node *avlTree::rl_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside rl rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->right;
parent->right = ll_rotation(temp);
return rr_rotation(parent);
}
avl_node *avlTree::balance(avl_node *temp) {
int bal_factor = diff(temp);
if (bal_factor > 1) {
if (diff(temp->left) > 0)
temp = ll_rotation(temp);
else
temp = lr_rotation(temp);
} else if (bal_factor < -1) {
if (diff(temp->right) > 0)
temp = rl_rotation(temp);
else
temp = rr_rotation(temp);
}
return temp;
}
avl_node *avlTree::insert(avl_node *root, int value) {
//cout<<"Inside insert for val = "<<value<<endl;
if (root == NULL) {
root = new avl_node;
root->data = value;
root->left = NULL;
root->right = NULL;
return root;
} else if (value < root->data) {
root->left = insert(root->left, value);
root = balance(root);
} else if (value >= root->data) {
root->right = insert(root->right, value);
root = balance(root);
}
return root;
}
avl_node* avlTree::minValueNode(avl_node* node) {
avl_node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}
int avlTree::getBalance(avl_node* N) {
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
avl_node* avlTree::del(avl_node *root, int value) {
cout<<"del for val = "<<value<<endl;
if (root == NULL){
cout<<"root is null here\n";
return root;
}
// If the key to be deleted is smaller than the
// root's key, then it lies in left subtree
if (value < root->data)
root->left = del(root->left, value);
// If the key to be deleted is greater than the
// root's key, then it lies in right subtree
else if (value > root->data)
root->right = del(root->right, value);
// if key is same as root's key, then This is
// the node to be deleted
else {
// node with only one child or no child
if ((root->left == NULL) || (root->right == NULL)) {
avl_node* temp = root->left ? root->left : root->right;
// No child case
if (temp == NULL) {
temp = root;
root = NULL;
cout<<"Root set to null\n";
}
else{
// One child case
cout<<temp->data<<" copied to root "<<root->data<<"\n";
*root = *temp;
// Copy the contents of
// the non-empty child
}
free(temp);
} else {
// node with two children: Get the inorder
// successor (smallest in the right subtree)
avl_node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node
root->data = temp->data;
// Delete the inorder successor
root->right = del(root->right, temp->data);
}
} // If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
//root->height = 1 + max(height(root->left),height(root->right));
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to
// check whether this node became unbalanced)
int balance = getBalance(root);
cout<<"balance = "<<balance<<" for root "<<root->data<<endl;
if(root->right == NULL)
cout<<"yes null"<<endl;
// If this node becomes unbalanced, then there are 4 cases// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0){
cout<<"balance1 = "<<getBalance(root->left)<<" for root "<<root->left->data<<endl;
avl_node* t = rr_rotation(root);
//root = rr_rotation(root);
cout<<"Root of the modified sub-tree is "<<t->data<<endl;
return t;
//rr_rotation(root);
}
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0) {
cout<<"balance2 = "<<getBalance(root->left)<<" for root "<<root->left->data<<endl;
cout<<"prev root "<<root->left->data<<endl;
//root->left = ll_rotation(root->left);
root = lr_rotation(root);
cout<<"new root "<<root->data<<endl;
//return rr_rotation(root);
return root;
} // Right Right Case
if (balance < -1 && getBalance(root->right) <= 0){
cout<<"balance3 = "<<getBalance(root->right)<<" for root "<<root->right->data<<endl;
avl_node* t = rr_rotation(root);
cout<<"Root of the modified sub-tree is "<<t->data<<endl;
return t;
//return ll_rotation(root);
}
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
cout<<"balance4 = "<<getBalance(root->right)<<" for root "<<root->right->data<<endl;
//root->right = rr_rotation(root->right);
//return ll_rotation(root);
return rl_rotation(root);
}
return root;
}
void avlTree::inorder(avl_node *tree) {
if (tree == NULL)
return;
inorder(tree->left);
cout << tree->data << " ";
inorder(tree->right);
}
void avlTree::preorder(avl_node *tree) {
if (tree == NULL)
return;
cout << tree->data << " ";
preorder(tree->left);
preorder(tree->right);
}
int avlTree::getSize(avl_node* N){
if(N == NULL)
return 0;
return (getSize(N->left) + 1 + getSize(N->right));
}
int avlTree::kthsmallest(avl_node* N, int k){
int r = getSize(N->left) + 1;
if(k == r)
return N->data;
if(k < r)
return kthsmallest(N->left,k);
if(k > r)
return kthsmallest(N->right,k-r);
return -1;
}
int main(void) {
int n, i, x;
char s;
avlTree tree; for(i=0;i<12;i++){
root = tree.insert(root,i);
tree.preorder(root);
cout<<endl;
}
for(i=4;i<=6;i++){
root = tree.del(root,6);
tree.preorder(root);
cout<<endl;
}
return 0;
}
I have two problems where I'm having a hard time to understand.
1) I'm having a hard time to understand how to pass my L1 doublyLinkedList into an array so that I can save each list of numbers my txt file reads
2) If I have an uneven negative number my break_into_nodes() method is reading an error as stoi is creating 1 node for a negative sign, how would I create an if statement to continue to breaking it into a node
#include "stdafx.h"
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <cstdlib>
#include "ArgumentManager.h"
using namespace std;
struct Node
{
long long value;
Node *next, *prev;
Node(long long y)
{
value = y;
next = prev = NULL;
}
};
class doubleLinkedList
{
Node *back;
public:
Node *front;
doubleLinkedList() { front = NULL; back = NULL; }
~doubleLinkedList() { destroyList(); }
doubleLinkedList(const string& num, int digitsPerNode) {
appendNodeFront(stoi(num, 0, 10));
}
void appendNodeFront(long int x);
void dispNodesForward(int digits);
void destroyList();
void clean();
};
void doubleLinkedList::clean()
{
destroyList();
}
void doubleLinkedList::appendNodeFront(long int x)
{
Node *n = new Node(x);
if (front == NULL)
{
front = n;
//back = n;
}
else
{
front->prev = n;
n->next = front;
front = n;
}
}
void doubleLinkedList::dispNodesForward(int digits)
{
Node *temp = front;
int temp_val;
if (temp != NULL)
{
/* First node does not get Zero padding */
temp_val = (int)temp->value;
printf("%d", temp_val);
temp = temp->next;
while (temp != NULL)
{
temp_val = (int)temp->value;
printf("%0*d", digits, temp_val);
temp = temp->next;
}
}
}
void doubleLinkedList::destroyList()
{
Node *T = back;
while (T != NULL)
{
Node *T2 = T;
T = T->prev;
delete T2;
}
front = NULL;
back = NULL;
}
void break_into_nodes(doubleLinkedList *list, string number, int digits) {
string node_value;
int num_index, num_iterations;
int i, j;
num_index = number.length();
if (num_index < digits)
{
node_value = number;
list->appendNodeFront(stoi(node_value));
}
else {
/* adjust for incomplete nodes */
if ((number.length() % digits) == 0)
num_iterations = (number.length() / digits);
else
num_iterations = (number.length() / digits) + 1;
for (j = 0; j < num_iterations; j++) {
node_value.clear();
for (i = 0; i < digits; i++) {
num_index--;
if (num_index < 0)
break;
node_value = node_value.insert(0, number.substr(num_index, 1));
}
list->appendNodeFront(stoi(node_value));
}
}
}
// Driver program
int main(int argc, char* argv[]) {
doubleLinkedList l1;
if (argc < 2) {
cerr << "Usage: infinitearithmetic \"input=xyz.txt;digitsPerNode= <number>\"\n";
}
ArgumentManager am(argc, argv);
string filename = am.get("input");
/* Digits per Node ar from 1 to 8 */
int digitsPerNode = stoi(am.get("digitsPerNode"));
ifstream ifs(filename.c_str());
string line;
string num1;
int i = 0;
while (!ifs.eof())
{
getline(ifs, line);
//cout << "" << line << endl;
num1 = line;
break_into_nodes(&l1, num1, digitsPerNode);
l1.dispNodesForward(digitsPerNode);
cout << endl;
l1.clean();
i++;
}
return 0;
}
I am working on an exercise in processing an AVL tree. The debugger shows no errors. I ran the program and it is supposed to output an output text file. However the program crashes every time.
#include <stdio.h>
#include <assert.h>
#include <algorithm>
#include <vector>
using namespace std;
struct node
{
int key;
int height;
node *left, *right;
node(int k)
{
key = k;
height = 1;
left = right = 0;
}
};
void pre_order(node* root)
{
if(root == 0) return;
printf("%d", root->key);
printf(" ");
pre_order(root->left);
pre_order(root->right);
}
void in_order(node* root)
{
in_order(root->left);
printf("%d", root->key);
printf(" ");
in_order(root->right);
}
int height(node* r)
{
return r ? r->height : 0;
}
void update_height(node* root)
{
if(root == 0) return;
int hl = height(root->left), hr = height(root->right);
root->height = std::max(hl, hr) + 1;
}
node* right_rotate(node* ref_root)
{
assert(ref_root && ref_root->left);
node *a = ref_root, *b = ref_root->left;
a->left = b->right;
b->right = a;
update_height(a);
update_height(b);
return b;
}
node* left_rotate(node* ref_root)
{
assert(ref_root && ref_root->right);
node *c = ref_root, *d = ref_root->right;
c->right = d->left;
d->left = c;
update_height(c);
update_height(d);
return d;
}
node* maintain(node* ref_root)
{
if(ref_root == 0) return ref_root;
update_height(ref_root);
node* ret = ref_root;
if(height(ref_root->left) > height(ref_root->right) + 1)
{
node* p = ref_root->left;
if( height(p->left) < height(p->right) )
ref_root->left = left_rotate(p);
ret = right_rotate(ref_root);
}
else if(height(ref_root->right) > height(ref_root->left) + 1)
{
node* p = ref_root->right;
if(height(p->right) < height(p->left)){
ref_root->right = right_rotate(p);
}
ret = left_rotate(ref_root);
}
return ret;
}
node* insert_key(int key, node* ref_root)
{
if(ref_root == 0)
{
return ref_root = new node(key);
}
if(key < ref_root->key){
node* child = insert_key(key, ref_root->left);
ref_root->left = child;
}
else if(key > ref_root->key){
node* child = insert_key(key, ref_root->right);
ref_root->right = child;
}
else
assert(0);
return maintain(ref_root);
}
vector<node*> minimum(node* T) {
vector<node*> x;
node* y = T;
while (y->left != NULL) {
x.push_back(y->left);
}
return x;
}
node* delete_key(int key, node* ref_root)
{
if(key < ref_root->key){
node* child = delete_key(key, ref_root->left);
ref_root->left = child;
}
else if(key > ref_root->key){
node* child = delete_key(key, ref_root->right);
ref_root->right = child;
}
else
{
if(ref_root->left && ref_root->right)
{
vector <node*> y = minimum(ref_root->right);
node* successor = y.back();
node* sParent = y[y.size()-2];
ref_root->key = successor->key;
sParent->left = successor->right;
}
else
{
if(ref_root->left != NULL){
ref_root = ref_root->left;
}
else if(ref_root->right != NULL){
ref_root = ref_root->right;
}
}
}
return maintain(ref_root);
}
int main()
{
node *root = 0;
char op[10] = "";
int k;
while(true)
{
scanf("%s", op);
if(op[0] == 'E') break;
switch(op[0])
{
case 'A': scanf("%d", &k); root = insert_key(k, root); break; //Insert
case 'D': scanf("%d", &k); root = delete_key(k, root); break;//Delete
case 'P': pre_order(root); printf("\n"); break;//preorder
case 'I': in_order(root); printf("\n"); break;//inorder
default: assert(0);
}
}
return 0;
}
There is no check in the in_order function that root is not NULL.
I'm writing a function that counts the leaf nodes of a height balanced tree using struct and pointers. The function takes 3 arguments: the tree, pointer to an array and the maximum depth of the tree. The length of the array is the maximum depth. When function is called the array is initialized to zero. The function recursively follows the tree structure,
keeping track of the depth, and increments the right counter whenever it reaches a leaf. The function does not follow any pointer deeper than maxdepth. The function returns 0 if there was no leaf at depth greater than maxdepth, and 1 if there was some pointer togreater depth. What is wrong with my code. Thanks.
typedef int object;
typedef int key;
typedef struct tree_struct { key key;
struct tree_struct *left;
struct tree_struct *right;
int height;
} tree_n;
int count_d (tree_n *tr, int *count, int mdepth)
{
tree_n *tmp;
int i;
if (*(count + 0) == NULL){
for (i =0; i<mdepth; i++){
*(count + i) = 0;
}
}
while (medepth != 0)
{
if (tr == NULL) return;
else if ( tree-> left == NULL || tree->right == NULL){
return (0);
}
else {
tmp = tr;
*(count + 0) = 1;
int c = 1;
while(tmp->left != NULL && tmp->right != NULL){
if(tmp-> left){
*(count + c) = 2*c;
tmp = tmp->left;
return count_d(tmp, count , mdepth);
}
else if(tmp->right){
*(count + c + 1) = 2*c + 1;
tmp = tmp->right;
return count_d(tmp,count, mdepth);
}
c++;
mpth--;
}
}
}
What is wrong with my code
One thing I noticed is that you are missing return in the recursive calls.
return count_d(tmp, count , mdepth);
// ^^^ Missing
There are two such calls. Make sure to add return to both of them.
Disclaimer: Fixing this may not fix all your problems.
Correct Function To Insert,Count All Nodes and Count Leaf Nodes
#pragma once
typedef int itemtype;
#include<iostream>
typedef int itemtype;
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
class Node
{
public:
Node* left;
Node* right;
itemtype data;
};
class BT
{
private:
int count = 0;
Node* root;
void insert(itemtype d, Node* temp);//Override Function
public:
BT();//Constructor
bool isEmpty();
Node* newNode(itemtype d);
Node* getroot();
void insert(itemtype d);//Function to call in main
int countLeafNodes(Node * temp);
int countAllNodes();//to count all nodes
}
BT::BT()//constructor
{
root = NULL;
}
bool BT::isEmpty()
{
if (root == NULL)
return true;
else
return false;
}
Node* BT::newNode(itemtype d)
{
Node* n = new Node;
n->left = NULL;
n->data = d;
n->right = NULL;
return n;
}
void BT::insert(itemtype d)//Function to call in main
{
if (isEmpty())
{
Node* temp = newNode(d);
root = temp;
}
else
{
Node* temp = root;
insert(d, temp);
}
count++;//to count number of inserted nodes
}
void BT::insert(itemtype d, Node* temp)//Private Function which is overrided
{
if (d <= temp->data)
{
if (temp->left == NULL)
{
Node* n = newNode(d);
temp->left = n;
}
else
{
temp = temp->left;
insert(d, temp);
}
}
else
{
if (temp->right == NULL)
{
temp->right = newNode(d);
}
else
{
temp = temp->right;
insert(d, temp);
}
}
}
int BT::countAllNodes()
{ return count; }
int BT::countLeafNodes(Node* temp)
{
int leaf = 0;
if (temp == NULL)
return leaf;
if (temp->left == NULL && temp->right == NULL)
return ++leaf;
else
{
leaf = countLeafNodes(temp->left) + countLeafNodes(temp->right);
return leaf;
}
}
void main()
{
BT t;
t.insert(7);
t.insert(2);
t.insert(3);
t.insert(15);
t.insert(11);
t.insert(17);
t.insert(18);
cout<<"Total Number Of Nodes:" <<t.countAllNodes() <<endl;
cout << "Leaf Nodes:" << t.countLeafNodes(t.getroot()) << endl;
_getch();
}
Output:
Ouput