C++ Return does not work - c++

Adding an element to the AVL tree. Tree currently has no elements. I am trying to add one. Function add performs ok, except program freezes and ends in 2 secs when it comes to return new node(k). Why is that?
struct node
{
int key;
unsigned char height;
node *left;
node *right;
node(int k) {key = k; left = right = 0; height = 1;}
};
node *root;
node *add(node* p, int k)
{
if(!p)
{
return new node(k);
}
if(k < p->key)
p->left = add(p->left,k);
else
p->right = add(p->right,k);
return balance(p);
}
int main()
{
root = NULL;
add(root, 10);
printf("%d",root->key);
return 0;
}

Your function returns a value, and you want to use it. But you're not saving it anywhere. In particular, you seem to be expecting root to contain the new node. So you have to do:
root = add(root, 10);

Related

Why do we return a pointer to a node instead of void function for avl tree implementation?

Okay so I seem to have gotten a bit lost. I am trying to insert data into a tree and when checking for balance and whether or not to rotate, I default to checking through the root. When I check examples online, I see that we can also rotate along other nodes in the tree as well. How do we figure out which node to use to balance the tree and how do we reach said node? I also saw that instead of having void functions to implement the insert and rotation functions, people use a node pointer return type instead. What is the purpose of that? I know the answers may be super obvious I am just lost.
struct TNode{
int data;
TNode* left;
TNode* right;
};
class Tree{
public:
TNode* root;
public:
Tree()
{root = nullptr;}
int height(TNode* node);
int balanceFactor(TNode* node);
bool isBalance(TNode* node)
{return balanceFactor(node)<-1 && balanceFactor(node)>1?true:false;}
void avlInsert(int key);
void LLRotation(TNode* node);
};
int Tree::height(TNode* node){
int l = 0;
int r = 0;
if(!node->left && !node->right)
return 0;
if(node->left)
l = height(node->left) + 1;
if(node->right)
r = height(node->right) + 1;
return l > r ? l : r;
}
int Tree::balanceFactor(TNode *node){
if(node->left && node->right)
return height(node->left) - height(node->right);
else if(node->left && !node->right)
return height(node);
else
return -1 * height(node);
}
void Tree::LLRotation(TNode *node){
TNode* nl = node->left;
node->left = nl->right;
nl->right = node;
if(root == node)
root = nl;
}
void Tree::avlInsert(int key){
TNode* trav;
TNode* follow;
TNode* node = new TNode;
node->data = key;
node->left = nullptr;
node->right = nullptr;
if (!root)
root = node;
else{
trav = root;
while (trav){
if (key < trav->data){
follow = trav;
trav = trav->left;
}
else{
follow = trav;
trav = trav->right;
}
}
if(key < follow->data)
follow->left = node;
else
follow->right = node;
}
if (balanceFactor(root) == 2 && balanceFactor(root->left) == 1)
LLRotation(root);
}
It really depends on your implementation some people they want to return a node, using a void function does not change the result much. For insert function you need to check only after you insert the node so you can go ahead and insert that node than rotate it. Please note that this function will only work if you have an AVL Tree to start with. Also your code is not correct, below:
if (balanceFactor(root) == 2 && balanceFactor(root->left) == 1)
LLRotation(root);
This is not how you check it for insertion.... That's for deletion buddy, I think you are getting mixed up. Usually for insertion you check if the balanceFactor is between 1 and -1, so if you are getting 2, then it is a left heavy tree, in your case, because it is left-right, which means you should do Right rotation........ Buddy......
int l = 0;
int r = 0;
if(!node->left && !node->right)
return 0;
if(node->left)
l = height(node->left) + 1;
if(node->right)
r = height(node->right) + 1;
return l > r ? l : r;
Height function, extremely inefficient... Instead define height as a variable for node and then modify it after each insertion, deletion.

recursive code for finding the height of a binary tree

I am trying to find the height of a binary tree and here is my attempt at the same
#include<iostream>
#include<stack>
using namespace std;
int total = 0;
int length = -1;
class Node{
public:
int data;
Node *left;
Node *right;
Node(int k){
data = k;
left = right = NULL;
}
};
void height(Node *root){
if(root==NULL)
return;
length++;
if(length>total)
total = length;
height(root->left);
height(root->right);
}
int main(){
Node *root = new Node(3);
root->left = new Node(4);
root->left->left = new Node(5);
root->right = new Node(6);
root->right->left = new Node(7);
height(root);
cout<<total;
return 0;
}
here length and total have been declared as global variables having values -1 and 0 respectively.
When I run the code, the output which I am getting is the number of nodes in the tree - 1 but not the height of the tree. Please let me know my mistake here.
Sure, you're incrementing length on every node.
If you're doing it recursively, it is actually very simple:
std::size_t height(Node const *root) {
if(!root) return 0;
return 1 + std::max(height(root->left), height(root->right));
}
Your approach is more of a backtracking than a simple recursion. In this approach you should be mindful to revert back to the original state at each step. Here length is always being incremented. You should revert it back.
void height(Node *root){
if(root==NULL)
return;
length++;
total = std::max(total,length+1); // Either this or initialize length as 0
height(root->left);
height(root->right);
length--; // <--- Add this line
}

Pointer of struct changes

#include<stack>
#include<iostream>
class Tree{
private:
struct tree{
int val;
tree * lChild;
tree * rChild;
tree * Parent;
};
tree *root;
public:
Tree();
void insert(int x);
};
Tree::Tree(){
root = NULL;
std::cout<<"ROOT inside constructor : "<<root<<std::endl;
}
void Tree::insert(int x){
tree *wst;
wst->val = x;
wst->lChild = NULL;
wst->rChild = NULL;
tree *temp = root;
tree *p = NULL;
std::cout<<"ROOT inside insert : "<<root<<std::endl;
while(temp != NULL){
p = temp;
if(x < temp->val)
temp = temp->lChild;
else
temp = temp->rChild;
}
std::cout<<x<<std::endl;
wst->Parent = p;
if(p == NULL){
root = wst;
}
else{
if(x < p->val)
p->lChild = wst;
else
p->rChild = wst;
}
}
int main(){
Tree tree;
tree.insert(404);
}
I want to check if pointer root is equal to NULL, but it does not seems too work. It seems like the pointer changes from 0 to 0x4 when I am inside the method insert. How can I check if pointer of struct is equal NULL?
EDIT In the insert method if tree doesn't have any nodes it should not enter first while loop, as root should be equall NULL. And my problem is that it enters this loop anyway and crashes when it checks for temp childrens(that are still not defined).
What does wst point to?
tree *wst;
wst->val = x;
wst->lChild = NULL;
wst->rChild = NULL;
// [...]
wst->Parent = p;
Whoops! Your program has undefined behaviour. No wonder it crashes. :)
You probably need tree* wst = new tree(); there. Don't forget to delete your nodes in the Tree destructor, too!
And I'd advise against having a type Tree plus a type tree; perhaps call the latter Node instead?

Binary search tree traversal

Hi guys I have a doubt in inserting a new node in BST. In the addNode module I am trying to insert an element in the BST, but each time while adding a new node it is adding to the same root node which I passed from main function initially without traversing inside the tree.
This is the code which I have written.
#include<stdio.h>
#include<stdlib.h>
#include<cstdio>
#include<iostream>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
struct node* newNode(int data)
{
node* temp = (node*)malloc(sizeof(struct node));
//struct temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return(temp);
};
int addNode(node *dest, node *root)
{
if(root == NULL)
{
cout<<"adding data to node for "<< dest->data<<endl;
root = dest;
cout<<"ROOT VALUE = root->data "<<root->data<<endl;
return 1;
}
if(dest->data > root->data)
{
cout<<"Traverse right for "<<dest->data<<endl;
addNode(dest, root->right);
}
else if(dest->data < root->data)
{
cout<<"Traverse left for "<<dest->data<<endl;
addNode(dest, root->left);
}
}
void printNodes(node *root)
{
if(root != NULL)
{
printNodes(root->left);
if(root->left != NULL && root->right != NULL)
std::cout<< root->data <<" ";
printNodes(root->right);
}
}
int main()
{
int i, j, k, flag;
int arr[6] = {4, 2,8, 1, 0, 10};
node *start = newNode(arr[0]);
for(i = 1; i < 6; i++)
{
node *newOne = newNode(0);
newOne->data = arr[i];
cout<<"NODE DATA - start->data "<<start->data;
if(addNode(newOne, start))
std::cout<<"\nNode added"<<endl;
}
printNodes(start);
return 1;
}
I am quite new to trees concept as well as pointers concept in trees. Any help is appreciated and thank you.
... but each time while adding a new node it is adding to the same root
node
This is because you are adding it always to the same root, as here
if(addNode(newOne, start))
start is always the same. You could make addNode return the new root and call it like that:
start = addNode(newOne,start);
I'll leave it to you to implement it.
Note that parameters are always passed by value in c++ (unless you pass-by-reference), thus changing the parameter inside the method, root = dest;, has no effect on the start in main.

Creating a double link list. Initializing the first 15 nodes

My insert method should have P as taking in the first value (0) and 15 being the last value of the link list. Though, when I print out my list, I have to go through p->succ instead of p-prev to print out the items, and it prints out 15, 14, 13....; is this right? or am i implementing my functions wrong?
class Node{
public:
int value;
Node *succ;
Node *prev;
Node(int val, Node *s=NULL, Node *p=NULL)
:value(val),succ(s),prev(p){}
Node *insert(Node *p,Node *n)
{
if(n==NULL)
return p;
if(p==NULL)
return n;
n->succ=p;
if(p->prev)
p->prev->succ=n;
n->prev=p->prev;
p->prev=n;
return n;
}
int main(int argc, char *argv[]) {
Node *p= NULL;
for(int i = 0; i<=15; i++){
p = insert(p, new Node(i));
}
while(p){
cout<<p->value;
head=p->succ;
}
You are adding your nodes at the beginning. So obviously the last one added will be the first. If you want the nodes in the order you added, you need to add the nodes at the end.
Node *insert(Node *p,Node *n)
{
Node * ptr;
if(n==NULL)
return p;
if(p==NULL)
return n;
ptr = p;
// Traverse to the end of the list
while(ptr->succ)
{
ptr = ptr->succ;
}
ptr->succ = n;
n->prev = ptr;
return p;
}