deletion in AVL tree is not working properly in C - c

if i input 15,7,22,3 into this AVL tree, and then i delete 22, the tree then displays only 15. what happened to 7 and 3?? also when i enter the data in this particular order -> 15,7,3,22 and then i delete 22, the program then seems to work fine, i get 15,7 and 3 as my output which is fully balanced. this is very strange. please help me out.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
int height;
};
struct node *tree=NULL;
int height(struct node *tree)
{
if(tree==NULL)
return -1;
else{
int lh=height(tree->left);
int rh=height(tree->right);
if(lh>rh)
return 1+lh;
else
return 1+rh;
}
}
int max(int a,int b)
{
return ((a < b)?b:a);
}
int getbalance(struct node *tree)
{
if(tree==NULL)
return 0;
return (height(tree->left)-height(tree->right));
}
struct node *rr(struct node *y)
{
struct node *x,*t2;
x=y->left;
t2=x->right;
x->right=y;
y->left=t2;
return x;
};
struct node *ll(struct node *x)
{
struct node *y,*t2;
y=x->right;
t2=x->left;
y->left=x;
x->right=t2;
return y;
};
struct node *newNode(int val)
{
struct node *ptr;
ptr=(struct node *)malloc(sizeof(struct node));
ptr->data=val;
ptr->left=ptr->right=NULL;
ptr->height=1;
return ptr;
};
struct node *create(struct node *tree,int val)
{
if(tree==NULL)
return newNode(val);
else if(val < tree->data)
tree->left=create(tree->left,val);
else if(val > tree->data)
tree->right=create(tree->right,val);
else
{
printf("\n duplicate value ignored");
return tree;
}
tree->height=1+max(height(tree->left),height(tree->right));
int balance=getbalance(tree);
if(balance>1 && val<tree->left->data)
return rr(tree);
else if(balance<-1 && val>tree->right->data)
return ll(tree);
else if(balance>1 && val>tree->left->data)
{
tree->left=ll(tree->left);
return rr(tree);
}
else if(balance<-1 && val<tree->right->data)
{
tree->right=rr(tree->right);
return ll(tree);
}
return tree;
};
struct node *inordersuccesor(struct node *tree)
{
struct node *ptr;
ptr=tree;
while(ptr->left!=NULL)
{
ptr=ptr->left;
}
return ptr;
}
struct node *delnode(struct node *tree,int val)
{
if(tree==NULL)
return 0;
else if(val<tree->data)
tree->left=delnode(tree->left,val);
else if(val>tree->data)
tree->right=delnode(tree->right,val);
else
{
struct node *temp;
if(tree->left==NULL)
{
temp=tree->right;
free(tree);
return temp;
}
else if(tree->right==NULL)
{
temp=tree->left;
free(tree);
return temp;
}
else
{
temp=inordersuccesor(tree->right);
tree->data=temp->data;
tree->right=delnode(tree->right,temp->data);
}
}
int balance=getbalance(tree);
if(balance==2 && getbalance(tree->left)>=0)
return rr(tree);
else if(balance==2 && getbalance(tree->left)==-1)
{
tree->left=ll(tree->left);
return rr(tree);
}
else if(balance==-2 && getbalance(tree->right)<=-0)
return ll(tree);
else if(balance==-2 && getbalance(tree->right)==1)
{
tree->right=rr(tree->right);
return ll(tree);
}
return tree;
};
void display(struct node *tree)
{
if(tree!=NULL)
{
display(tree->left);
printf("\t%d",tree->data);
display(tree->right);
}
}
int main()
{
int val,option;
do{
printf("\n 1. create");
printf("\n 2. display");
printf("\n 3. find height");
printf("\n 4. balance factor");
printf("\n 5. delete node");
printf("\n 6. exit\n");
scanf("%d",&option);
switch(option)
{
case 1: printf("\n enter val: ");
scanf("%d",&val);
tree=create(tree,val);
break;
case 2: display(tree);
break;
case 3:
printf("\n height [%d]\n",height(tree));
break;
case 4:
printf("\n balance factor = [%d]",getbalance(tree));
break;
case 5:
printf("\n delete node: ");
scanf("%d",&val);
delnode(tree,val);
break;
}
}while(option!=6);
}

Related

Why my code can't display the pre_order after deleting a node which had two child nodes?

Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
struct node
{
struct node *left;
int data;
struct node *right;
};
struct node *fnode = NULL;
void insert(int val)
{
struct node *ptr = (struct node *) malloc(sizeof(struct node));
struct node *parentptr, *nodeptr;
ptr->data = val;
ptr->left = NULL;
ptr->right = NULL;
if(fnode == NULL)
{
fnode = ptr;
}
else
{
parentptr = NULL;
nodeptr = fnode;
while(nodeptr!=NULL)
{
parentptr = nodeptr;
if(val<nodeptr->data)
nodeptr = nodeptr->left;
else
nodeptr = nodeptr->right;
}
if(val<parentptr->data)
parentptr->left = ptr;
else
parentptr->right = ptr;
}
}
void pre_order(struct node *tree)
{
if(tree!=NULL)
{
printf("%i ",tree->data);
if(tree->left)
pre_order(tree->left);
if(tree->right)
pre_order(tree->right);
}
}
void in_order(struct node *tree)
{
if(tree)
{
in_order(tree->left);
printf("%i ",tree->data);
in_order(tree->right);
}
}
void post_order(struct node *tree)
{
if(tree)
{
post_order(tree->left);
post_order(tree->right);
printf("%i ",tree->data);
}
}
struct node *smallest_element(struct node *tree)
{
if(tree==NULL || tree->left == NULL)
return tree;
else
return smallest_element(tree->left);
}
struct node *largest_element(struct node *tree)
{
if(tree== NULL || tree->right==NULL)
return tree;
else
{
return largest_element(tree->right);
}
}
struct node *delete_element(struct node *tree, int val)
{
// some declarations
struct node *parent, *child;
child = parent = tree;
bool doesnt_exist = false;
// finding the node to be deleted and its corresponding parent
while(child->data!=val)
{
parent = child;
if(val < child->data)
child = child->left;
else
child = child->right;
if(child==NULL)
{
doesnt_exist = true;
break;
}
}
// if no node exists, print not found
if(doesnt_exist)
{
printf("\nThe node does not exist in the BST.");
return tree;
}
// if node exists
else
{
//if parent node is to be deleted
if(child==parent)
{
//if only parent node exists in the tree
if(child->left == NULL && child->right == NULL)
{
free(child);
tree = NULL;
return tree;
}
// deleting the parent node and replacing it by left-subtree's highest element
struct node *temp = tree->left;
struct node *pre_temp = tree->left;
//searching for left subtree's max element and its parent
while(temp->right!=NULL)
{
pre_temp = temp;
temp = temp->right;
}
//changing the deleted node's value with left subtree's highest element
child->data = temp->data;
//making the ex-position of changed element point to null
if(pre_temp->right == temp)
{
pre_temp->right = NULL;
}
else
{
pre_temp->left = NULL;
}
//freeing the ex-position of changed element.
free(temp);
}
else
{
// if the node to be deleted has 2 nodes
if(child->left && child->right)
{
//some declarations
struct node *temp = child->left;
struct node *pretemp = child;
//browsing to the maximum node on left subtree
while(temp->right!=NULL)
{
pretemp = temp;
temp = temp->right;
}
//exchanging left subtree's max with element to be deleted
child->data = temp->data;
//making the temp's parent point to null
if(pretemp->left == temp)
pretemp->left = NULL;
else
pretemp->right = NULL;
//freeing temp;
free(temp);
}
//if the node to be deleted has only right node
else if(child->left == NULL && child->right)
{
if(parent->left==child)
{
parent->left = child->right;
}
else
{
parent->right = child->right;
}
free(child);
return tree;
}
// if the node to be deleted has only left node
else if(child->right==NULL && child->left)
{
if(parent->left==child)
{
parent->left = child->left;
}
else
{
parent->right = child->left;
}
free(child);
return tree;
}
//if the node to be deleted has no children
else
{
if(parent->left == child)
parent->left = NULL;
else
parent->right = NULL;
free(child);
return tree;
}
}
}
}
int main()
{
int decision;
struct node *ptr;
int ip;
do
{
printf("\n ********MAIN MENU********");
printf("\n 1. Insert element");
printf("\n 2. Pre-order Traversal");
printf("\n 3. In-order Traversal");
printf("\n 4. Post-order Traversal");
printf("\n 5. Find smallest element");
printf("\n 6. Find largest element");
printf("\n 7. Delete an element");
printf("\n 8. Exit");
printf("\nEnter your choice:");
scanf("%i",&decision);
switch(decision)
{
case 1:
printf("\nEnter the element to be inserted:");
scanf("%i",&ip);
insert(ip);
break;
case 2:
if(fnode)
{
printf("\nThe pre-order traversal is as follows:\n");
pre_order(fnode);
}
else
{
printf("\nThe BST is empty!!!");
}
break;
case 3:
if(fnode)
{
printf("\nThe in-order traversal is as follows:\n");
in_order(fnode);
}
else
{
printf("\nThe BST is empty!!!");
}
break;
case 4:
if(fnode)
{
printf("\nThe post-order traversal is as follows:\n");
post_order(fnode);
}
else
{
printf("\nThe BST is empty!!!");
}
break;
case 5:
ptr = smallest_element(fnode);
if(ptr)
{
printf("\nThe smallest element is: %i",ptr->data);
}
else
{
printf("\nThe BST is empty!!!");
}
break;
case 6:
ptr = largest_element(fnode);
if(ptr)
{
printf("\nThe largest element is: %i",ptr->data);
}
else
{
printf("\nThe BST is empty!!!");
}
break;
case 7:
printf("\nEnter the element you want to delete:");
scanf("%i",&ip);
fnode = delete_element(fnode,ip);
break;
}
}
while(decision!=8);
return 0;
}
After I delete a node which had two child nodes, the resultant BST is formed properly (I verified it through debug tools). I have added all the possible cases for deleting a node from BST (has 0/1/2 child nodes and I have handled everything).
But when I make it to print the preorder/postorder/inorder traversal, the program just exits. Can u suggest me why is it so?

simple linked list program in c

//I implemented simple linked list progam in c
here i implement insert at first,last,particular position..
these error occured on execution :expected '=', ',', ';', 'asm' or 'attribute' before '*' token
..Anyone can please clarify what is these error
#include<stdio.h>
#include<malloc.h>
#define ISEMPTY printf("\n empty list");
struct node{
int value;
struct node *next;
}
startnode * create_node(int);
void insert_node_first();
void insert_node_last();
void insert_node_position();
typedef struct node start_node;
start_node *newnode,*ptr,*prev,*temp;
start_node *first=NULL,*last=NULL;
int main()
{
int ch;
char ans='Y';
while(ans == 'Y' || ans == 'y')
{
printf("\n Single linked list \n");
printf("\n1.INSERT NODE AT FIRST");
printf("\n2.INSERT NODE AT LAST");
printf("\n3.INSERT NODE AT POSITION");
printf("\n ENTER YOUR CHOICE");
scanf("%d",&ch);
switch(ans)
{
case 1:printf("INSERT NODE AT FIRST");insert_node_first();break;
case 2:printf("INSERT NODE AT LAST");insert_node_last();break;
case 3:printf("INSERT NODE AT POSITION");insert_node_position;break;
default:printf("U DIDN'T SELECT ANYTHING SO EXCEED");
}
printf("DO YOU WANT TO CONTINUE");
scanf("%c",&ans);
}
return 0;
}
start_node* create_node(int val)
{
newnode=(start_node *)malloc(sizeof(start_node));
if(newnode==NULL)
{
printf("\n Memory not allocated");
return 0;
}
else{
newnode->value=val;
newnode->next=NULL;
return newnode;
}
}
void insert_node_first()
{
int val;
printf("Enter the value for the node");
scanf("%d",&val);
newnode=create_node(val);
if(first == last && first == NULL)
{
first=last=newnode;
first->next=NULL;
last->next=NULL;
}
else{
temp=first;
first=newnode;
first->next=temp;
}
printf("\n inserted");
}
void insert_node_last()
{
int val;
printf("Enter the value insert at last");
scanf("%d",&val);
newnode=create_node(val);
if(first == last && first == NULL)
{
first=last=newnode;
first->next=NULL;
last->next=NULL;
}
else{
last->next=newnode;
last=newnode;
last->next=NULL;
}
}
void insert_node_position()
{
int val,position,count,i;
printf("Enter the value to insert");
scanf("%d",&val);
newnode=create_node(val);
printf("Enter the position you want to ");
scanf("%d",&position);
ptr=first;
while(ptr !=NULL)
{
ptr=ptr->next;
count++;
}
if(position == 1)
{
if(first == last && first == NULL)
{
first=last=newnode;
first->next=NULL;
last->next=NULL;
}
else{
temp=first;
first=newnode;
first->next=temp;
}
}
else if(position > 1 && position<=count)
{
ptr=first;
for(i=1;i<position;i++)
{
prev=ptr;
ptr=ptr->next;
}
prev->next=newnode;
newnode->next=ptr;
printf("inserted at position");
}else{
printf("position is out of range");
}
}
Change startnode with start_node and move
start_node * create_node(int);
After
typedef struct node start_node;
Otherwise the compiler does not know, at that point, what is start_node;
Moreover you forgot a ; on struct declaration
struct node{
int value;
struct node *next;
};

linked list insertion operation and display

I am trying to implement a singly linked list and performing insertion operations.The program compiles and runs but whenever i try to display its elements.It doesn't show the elements.I am not able to find out the error.
#include <stdio.h>
#include <stdlib.h>
struct n
{
int data;
struct n *next;
};
typedef struct n node;
node *insert_at_front(node *start,int info)
{
node *temp,*p;
temp=(node *)malloc(sizeof(node));
temp->data=info;
temp->next=start;
start=temp;
return start;
}
node *insert_at_end(node *start,int info)
{
node *temp,*p;
temp=(node *)malloc(sizeof(node));
if(start==NULL)
{
printf("Empty\n");
return start;
}
else
{
for(p=start; p->next!=NULL; p=p->next)
{
if(p->next==NULL)
{
temp->data=info;
temp->next=p->next;
p->next=temp;
}
}
}
return start;
}
node *insert_after(node *start,int info,int dat)
{
node *temp,*p;
temp=(node *)malloc(sizeof(node));
for(p=start; p->next!=NULL; p=p->next)
{
if(p->data==dat)
{
temp->data=info;
temp->next=p->next;
p->next=temp;
}
}
return start;
}
void display(node *start)
{
node *temp;
if(start==NULL)
{
printf("List is Empty\n");
return ;
}
temp=start;
while(temp!=NULL)
{
printf("%d-->",temp->data);
temp=temp->next;
}
printf("\n\n");
}
int main()
{
int value;
node *start=NULL;
int choice,data1;
while(1)
{
printf("\n1.insert_at_start\n2.insert at end.\n3.insert_after");
printf("\n4.display\n");
printf("enter choice\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter value\n");
scanf("%d",&value);
insert_at_front(start,value);
break;
case 2:
printf("Enter value\n");
scanf("%d",&value);
insert_at_end(start,value);
break;
case 3:
printf("Enter value\n");
printf("Enter value after which you want to insert\n");
scanf("%d%d",&value,&data1);
insert_after(start,value,data1);
break;
case 4:
display(start);
break;
default:
break;
}
}
return 0;
}
One problem with your code is that you're not using the return values from the different insert procedures. This means that if you start with an empty list (NULL) there is no way that main can get a non-empty list back.
At least you need to update start, for example:
start = insert_at_front(start,value);

AddNew Function using Linked List In C

Question: Create a linked list containing values in the ascending values. Then write functions addNew() which will accept a value from the user and then call addBegin() and addafterValue() functions to add the input value in the appropriate place
e.g. consider the list is like this:
12,15,20,26 then if the user enters values 8, 16 & 30 the list will look like this: 8,12,15,16,20,26,30.
My program:
#include<stdio.h>
typedef struct node
{
int data;
struct node *next;
}NODE;
NODE *start=NULL;
void append()
{
NODE *temp,*ptr;
temp=(NODE *)malloc(sizeof(NODE));
printf("Enter data:");
scanf("%d",&temp->data);
temp->next=NULL;
if(start==NULL)
start=temp;
else
{
ptr=start;
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=temp;
}
}
void display()
{
NODE *ptr=start;
while(ptr!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
void addBegin(int val)
{
NODE *temp;
temp=(NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=start;
start=temp;
}
unsigned int addAfterValue(int val,NODE *ptr)
{
NODE *temp;
temp=(NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=ptr->next;
return temp;
}
void addNew()
{
int val;
unsigned int loc;
NODE *ptr=start;
printf("Enter value to add:");
scanf("%d",&val);
if(val<ptr->data) {
addBegin(val);
ptr=NULL;
}
while(ptr!=NULL) {
if(ptr->next!=NULL)
{
if(val<ptr->next->data)
{
addAfterValue(val,ptr);
ptr->next=loc;
ptr=NULL;
}
else
{
ptr=ptr->next;
}
}
if(ptr->next==NULL)
{
loc=addAfterValue(val,ptr);
ptr=NULL;
}
}
}
int main()
{
int ans;
do
{
printf("Enter [1]To append\n[2]To add new node\n[3]To display\n[0]To exit\n");
printf("Enter your choice:");
scanf("%d",&ans);
switch(ans)
{
case 1:
append();
break;
case 2:
addNew();
break;
case 3:
display();
break;
case 0:
break;
default:
printf("Wrong Input.Try again.");
}
}while(ans);
}
My doubt: The addBegin() function works perfectly. I think there's something wrong with addafterValue(). Can anyone help me by finding out my mistake?
Instead of passing the current pointer address.
Use the previous node pointer and assign to its next node.
void addAfterValue(int val,NODE *ptr)
{
NODE *temp = (NODE *)malloc(sizeof(NODE));
temp->data=val;
temp->next=ptr->next;
ptr->next = temp;
}
Change the addNew function
void addNew()
{
int val;
NODE *ptr=start;
NODE *prev= NULL;
printf("Enter value to add:");
scanf("%d",&val);
if( ptr == NULL || val < ptr->data)
{
addBegin(val);
return;
}
else
{
prev = ptr;
ptr=ptr->next;
}
while( ptr != NULL)
{
if( val <= ptr->data)
{
addAfterValue(val,prev);
return;
}
else
{
prev = ptr;
ptr=ptr->next;
}
}
/* Control comes here if the entire list is scanned.... Now append it to the end using prev pointer, as the new node is greater than all of the existing nodes */
}

How to perform insert, delete, and display an element into a linked list in C?

I'm working on a program in C which is not yet so familiar to me. It has choices on what to do with the linked list. But it has errors. So far, this is what I have.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
}*head;
void append(int num)
{
struct node *temp,*right;
temp= (struct node *)malloc(sizeof(struct node));
temp->data=num;
right=(struct node *)head;
while(right->next != NULL)
right=right->next;
right->next =temp;
right=temp;
right->next=NULL;
}
void add( int num )
{
struct node *temp;
temp=(struct node *)malloc(sizeof(struct node));
temp->data=num;
if (head== NULL)
{
head=temp;
head->next=NULL;
}
else
{
temp->next=head;
head=temp;
}
}
void addafter(int num, int loc)
{
int i;
struct node *temp,*left,*right;
right=head;
for(i=1;i<loc;i++)
{
left=right;
right=right->next;
}
temp=(struct node *)malloc(sizeof(struct node));
temp->data=num;
left->next=temp;
left=temp;
left->next=right;
return;
}
int count()
{
struct node *n;
int c=0;
n=head;
while(n!=NULL)
{
n=n->next;
c++;
}
return c;
}
void insert(int num)
{
int c=0;
struct node *temp;
temp=head;
if(temp==NULL)
{
add(num);
}
else
{
while(temp!=NULL)
{
if(temp->data<num)
c++;
temp=temp->next;
}
if(c==0)
add(num);
else if(c<count())
addafter(num,++c);
else
append(num);
}
}
int delete(int num)
{
struct node *temp, *prev;
temp=head;
while(temp!=NULL)
{
if(temp->data==num)
{
if(temp==head)
{
head=temp->next;
free(temp);
return 1;
}
else
{
prev->next=temp->next;
free(temp);
return 1;
}
}
else
{
prev=temp;
temp= temp->next;
}
}
return 0;
}
void display(struct node *r)
{
r=head;
if(r==NULL)
{
return;
}
while(r!=NULL)
{
printf("%d ",r->data);
r=r->next;
}
printf("\n");
}
int main()
{
int i,num;
struct node *n;
head=NULL;
while(1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Size\n");
printf("4.Delete\n");
printf("5.Exit\n");
printf("Enter your choice : ");
if(scanf("%d",&i)<=0){
printf("Enter only an Integer\n");
exit(0);
} else {
switch(i)
{
case 1: printf("Enter the number to insert : ");
scanf("%d",&num);
insert(num);
break;
case 2: if(head==NULL)
{
printf("List is Empty\n");
}
else
{
printf("Element(s) in the list are : ");
}
display(n);
break;
case 3: printf("Size of the list is %d\n",count());
break;
case 4: if(head==NULL)
printf("List is Empty\n");
else{
printf("Enter the number to delete : ");
scanf("%d",&num);
if(delete(num))
printf("%d deleted successfully\n",num);
else
printf("%d not found in the list\n",num);
}
break;
case 5: return 0;
default: printf("Invalid option\n");
}
}
}
return 0;
}
I made another working program. Take a look at this. You might have some additions, maybe?
#include <iostream>
#include <conio.h>
using namespace std;
class Node {
int data;
Node* next;
public:
Node() {};
void SetData(int aData) { data = aData; };
void SetNext(Node* aNext) { next = aNext; };
int Data() { return data; };
Node* Next() { return next; };
};
class List {
Node *head;
public:
List() { head = NULL; };
void Display();
void Append(int data);
void Remove(int data);
};
void List::Display() {
Node *tmp = head;
if ( tmp == NULL ) {
cout << "EMPTY" << endl;
return;
}
if ( tmp->Next() == NULL ) {
cout << tmp->Data();
cout << " --> ";
cout << "NULL" << endl;
}
else {
do {
cout << tmp->Data();
cout << " --> ";
tmp = tmp->Next();
} while ( tmp != NULL );
cout << "NULL" << endl;
}
}
void List::Append(int data) {
Node* newNode = new Node();
newNode->SetData(data);
newNode->SetNext(NULL);
Node *tmp = head;
if ( tmp != NULL ) {
while ( tmp->Next() != NULL ) {
tmp = tmp->Next();
}
tmp->SetNext(newNode);
}
else {
head = newNode;
}
}
void List::Remove(int data) {
Node *tmp = head;
if ( tmp == NULL )
return;
if ( tmp->Next() == NULL ) {
delete tmp;
head = NULL;
}
else {
Node *prev;
do {
if ( tmp->Data() == data ) break;
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
prev->SetNext(tmp->Next());
delete tmp;
}
}
int main() {
List list;
int n[100], i, size;
char choice;
for(i=1; i<=100; i++){
cout<<"Insert[I]\nDisplay[D]\nRemove[R]\n";
cin>>choice;
if (choice=='I'||choice=='i'){
cout<<"Enter the number of nodes: ";
cin>>size;
cout<<"Enter a number to be inserted:\n";
for(i=1; i<=size; i++){
cin>>n[i];
list.Append(n[i]);
}
}
if (choice=='D'||choice=='d'){
cout<<"Elements in the list are: ";
list.Display();
}
if (choice=='R'||choice=='r'){
cout<<"Enter a number to be removed: ";
cin>>n[i];
list.Remove(n[i]);
}
}
getch();
}

Resources