How to implement a function that iteratively creates a binary tree? - c

I tried to implement a binary tree by using an iterative function to create it. I'm quite confused about why I'm getting an infinite loop as my output. I believe that the function being used is not having problems. But if anyone can explain me what exactly is causing this error I would appreciate it.
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left,*right;
} NODE;
NODE* createNode(int ele){
NODE* newnode = (NODE*)malloc(sizeof(NODE));
newnode->data = ele;
newnode->left = NULL;
newnode->right = NULL;
return newnode;
}
void inorder(NODE* root){
while(root != NULL){
inorder(root->left);
printf(" %d ",root->data);
inorder(root->right);
}
}
void preorder(NODE* root){
while(root != NULL){
printf(" %d ",root->data);
preorder(root->left);
preorder(root->right);
}
}
void postorder(NODE* root){
while(root != NULL){
postorder(root->left);
postorder(root->right);
printf(" %d ",root->data);
}
}
void createTree(NODE** root, int ele){
NODE* newnode = createNode(ele);
if(*root == NULL){
//set newnode as root
*root = newnode;
return;
}
NODE* curr = *root;
while (1){
// If the data of the new node is less than the data of the current node,
// go to the left child
if(ele < curr->data){
// If the left child is empty, insert the new node here
if(curr->left == NULL){
curr->left = newnode;
return;
}
curr = curr->left;
}
// If the data of the new node is greater than or equal to the data of the current node,
// go to the right child
else{
if (curr->right == NULL){
curr->right = newnode;
return;
}
curr = curr->right;
}
}
}
int main(){
NODE* root = NULL;
int data;
while(1){
printf("Enter the data for the root node of the binary tree(Enter -1 to stop): \n");
scanf("%d",&data);
createTree(&root,data);
if(data == -1){
break;
}
}
printf("\nPreorder traversal:\n");
preorder(root);
printf("\nInorder traversal:\n");
inorder(root);
printf("\nPostorder traversal:\n");
postorder(root);
return 0;
}

In the print functions, the line
while(root != NULL){
will cause endless looping as root never change.
You probably want
if(root != NULL){

Related

C Binary Tree Deletion Not Working Inorder Print Causes Infinite Recursion

I'm learning binary trees, and I'm trying to delete a node from the binary tree. I get a segmentation fault after infinite recursion in the print in order function. It only does this after the delete function is called. I don't get why this happened. I think it should only happen if the last left pointer in the tree is set to something other than NULL, which would cause the if statement to return to never be triggered. The delete function in this particular case is deleting a node on the right so it shouldn't even touch anything on the left. Help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
struct Node{
//blueprint for node
int data;
struct Node *Left;
struct Node *Right;
};
struct Node *CreateNode(int data){
//utility function to create a new node
struct Node *newNode = malloc(sizeof(struct Node));
newNode->Left = NULL;
newNode->Right = NULL;
newNode->data = data;
return newNode;
}
struct Node *insertNode(struct Node *root, int num){
if(root == NULL){
root = CreateNode(num);
return root;
}
if(root->data >= num){
if(root->Left != NULL){
insertNode(root->Left, num);
}
else{
//if the node on the left of root is equal to NULL
//create a node
root->Left = CreateNode(num);
}
}
else{
if(root->Right != NULL){
insertNode(root->Right, num);
}
else{
//if the node on the right of root is equal to NULL
//create a node
root->Right = CreateNode(num);
}
}
}
void inOrderPrint(struct Node *Head){
//prints nodes in the binary tree in order
if(Head == NULL){
//if the head is null, stop doing recursion
return;
}
//recursivly calls itself and passes in the left node as a parameter
if(Head->Left != NULL){
inOrderPrint(Head->Left);
}
//prints out the data at the current node
printf("%d ", Head->data);
//recusivly calls itself and pases in the right node as a peramater
if(Head->Right != NULL){
inOrderPrint(Head->Right);
}
}
int getHeight(struct Node *Head){
//gets the height of the binary tree
if(Head == 0){
return -1;
}
int left = getHeight(Head->Left)+1;
int right = getHeight(Head->Right) + 1;
if(left > right){
return left;
}
else{
return right;
}
}
int childNum(struct Node *Head){
//returns the number of children the binary search tree node has (directly below it, not counting grand children)
if(Head->Left == NULL && Head->Right == NULL){
//if there is no child
return 0;
}
else if(Head->Left == NULL || Head->Right == NULL){
//if there 1 child
return 1;
}
else{
//if there are two children
return 2;
}
}
int getMax(struct Node *root){
if(root->Right == NULL){
return root->data;
}
else{
return getMax(root->Right);
}
}
struct Node *DeleteNode(struct Node *root, int num){
//function to delete a node from the binary search tree
if(root == NULL){
return root;
}
if(root->data == num){
//if this is the node to be deleted
int numberOfChildren = childNum(root);
if(numberOfChildren == 0){
printf("here??");
free(root);
return NULL;
}
else if(numberOfChildren == 1){
if(root->Left == NULL){
struct Node *temp = root->Right;
free(root);
return temp;
}
else{
struct Node *temp = root->Left;
free(root);
return temp;
}
}
else{
int max = getMax(root->Left);
root->data = max;
DeleteNode(root->Left, max);
return root;
}
}
else if(root->data >= num){
//if this node is greater than or equal to the node to be deleted, recur to the node on the left
root->Left = DeleteNode(root->Left, num);
}
else{
//if this node is less than the node to be deleted, recur to the node on rhe right
root->Right = DeleteNode(root->Right, num);
}
return root;
}
int main()
{
struct Node *root = NULL;
root = insertNode(root, 5);
insertNode(root, 10);
insertNode(root, 3);
insertNode(root, 14);
insertNode(root, 7);
insertNode(root, 16);
inOrderPrint(root);
printf("\nheight: %d", getHeight(root));
DeleteNode(root, 10);
printf("root left: %d", root->Left->data);
printf("\n");
inOrderPrint(root);
//sprintf(result, "%d/%f ...", int);
}

Binary tree deletion-cannot understand some pointers

I have a doubt in this binary tree deletion.The code is
#include<stdio.h>
#include<stdlib.h>
struct node
{
int key;
struct node *left, *right;
};
struct node *newNode(int item)
{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
void inorder(struct node *root)
{
if (root != NULL)
{
inorder(root->left);
printf("%d ", root->key);
inorder(root->right);
}
}
struct node* insert(struct node* node, int key)
{
if (node == NULL) return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
return node;
}
struct node * minValueNode(struct node* node)
{
struct node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}
struct node* deleteNode(struct node* root, int key)
{
if (root == NULL) return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else
{
if (root->left == NULL)
{
struct node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
struct node *temp = root->left;
free(root);
return temp;
}
struct node* temp = minValueNode(root->right);
root->key = temp->key;
root->right = deleteNode(root->right, temp->key);
}
return root;
}
int main()
{
struct node *root = NULL;
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 70);
root = insert(root, 60);
root = insert(root, 80);
printf("Inorder traversal of the given tree \n");
inorder(root);
printf("\nDelete 20\n");
root = deleteNode(root, 20);
printf("Inorder traversal of the modified tree \n");
inorder(root);
printf("\nDelete 30\n");
root = deleteNode(root, 30);
printf("Inorder traversal of the modified tree \n");
inorder(root);
printf("\nDelete 50\n");
root = deleteNode(root, 50);
printf("Inorder traversal of the modified tree \n");
inorder(root);
return 0;
}
The lines which I cannot understand is:
if (root->left == NULL)
{
struct node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
struct node *temp = root->left;
free(root);
return temp;
}
is this code actually return NULL value then can I rewrite the code as struct node *temp=NULL in both the cases but the last inorder value is not displayed when i do this.
The code you are inquiring about is part of the code handling the case that the node to delete is the root node of the tree. It checks whether the root node has only one child (or zero), in which case the deletion can be performed simply by making the one child the new root of the tree.
Note in particular that when root->left == NULL it is the right child, not the left one, that is chosen as the new root (and temporarily recorded in temp), and vice versa. Either way, the original root node is freed since it is no longer in the tree, and will not be accessible via the new root pointer that the function is about to return.
The function returns NULL only when the root node is initially the only node in the tree.

Deleting front node from a Singly Linked List in C

I am trying to delete from a Singly Linked List, however, when I try to delete from the first element, it prints garbage. I think the problem comes from the delete_node function, however, I tried everything and I cannot figure it out.
#include <stdio.h>//prinf
#include <stdlib.h>//alloc mallco callo
typedef struct node node;
struct node{
int number;
node *next;
};
node *new_node(int num){
node *n= (node*) malloc(sizeof(node));
n->number=num;
n->next=NULL;
return n;
}
void node_free_all(node *n){
if(n != NULL){
node_free_all(n->next);
free(n);
}
}
void print_nodes(node *n){
if(n != NULL){
print_nodes(n->next);
printf("Number is: %d\n",n->number);
}
}
void delete_node(node *n, int num){
node *rmNode= (node*)malloc(sizeof(node));
//delete first
if( n!= NULL && n->number==num){
rmNode = n;
n=n->next;
free(rmNode);
}
//all but first
while(n != NULL){
if(n->next != NULL && n->next->number == num){
rmNode= n->next;
n->next = rmNode->next;
free(rmNode);
break;
}
n=n->next;
}
}
int main(){
int i;
node *head= (node*) malloc(sizeof(node));
node *curr;
head=NULL;
for(i=1;i<=10;i++) {
curr = new_node(i);
curr->next =head;
head=curr;
}
printf("Everything:\n");
print_nodes(head);
printf("Deleting 1:\n");
delete_node(head,1);
print_nodes(head);
printf("Deleting 5:\n");
delete_node(head,5);
print_nodes(head);
printf("Deleting 2:\n");
delete_node(head,2);
print_nodes(head);
printf("Deleting 3:\n");
delete_node(head,3);
print_nodes(head);
printf("Deleting 10:\n");
delete_node(head,10);
print_nodes(head);
printf("Deleting 9:\n");
delete_node(head,9);
print_nodes(head);
node_free_all(head);
// node_free_all(list);
return 0;
}
What am I doing wrong?
You don't need to allocate memory to rmNode. Plus you need to pass the reference of head pointer to the function delete_node because every time you are updating the list and if you have to delete first element of list, then in this case head pointer also got updated.
struct node
{
int number;
node *next;
};
void delete_node(struct node** head_ref, int num)
{
struct node* temp;
struct node* current = (*head_ref);
//delete first
if( current != NULL && current->number == num)
{
temp = current;
current = current->next;
free(temp);
(*head_ref) = current;
}
else
{
//all but first
while(current != NULL)
{
if(current->next != NULL && current->next->number == num)
{
temp = current->next;
current->next = temp->next;
free(temp);
break;
}
current = current->next;
}
}
}
here's a version that removes all items that matches num, and always update the head item.
void delete_node(node** head_ref, int num)
{
node* temp;
node* last = 0;
node* current = *head_ref;
while(current)
{
if( current->number == num )
{
temp = current;
if( current == *head_ref )
current = (*head_ref) = current->next;
else
current = last->next = current->next;
free(temp);
} else {
last = current;
current = current->next;
}
}
}
You have to call it like delete_node(&head,1);
because it needs an address to the head item to be able to change it

Segmentation fault while doing malloc for a struct pointer

I trying to write basic Linked list code. I have two functions to add data to beginning of list and end of the list. Function to add data in the beginning works fine every time.
I am facing segmentation fault in insert_end function always.
I am getting the error while trying to access temp1 pointer to structure after doing malloc to it. But this is the same exact thing I am doing even in the insert_first function, but works every time. I tried googling it and tried in forums, no answer. Please help.
This link is my exact kinda problem.. but i dont understand the solution fully
Segmentation fault in C with malloc
I am getting error particularly on this block
struct node *temp1,*trav;
temp1 = (struct node *)malloc(sizeof(struct node));
trav = (struct node *)malloc(sizeof(struct node));
if (temp1 != NULL) { //******************Segmentation fault at this line**********
temp1->data = input;
}
#include<stdio.h>
#include<stdlib.h>
//*******Structure to hold linked list*********//
struct node {
int data;
struct node *next;
}*head,*temp;
//***********Function to Display everything**********//
void display(struct node *head) {
struct node *trav;
trav= (struct node *)malloc(sizeof(struct node));
printf("Entering into Display\n");
if (head == NULL) {
printf("Oh My God, the list is empty\n");
}
else {
trav = head;
while (trav != NULL) {
printf("Value stored in [%p] is [%d]\n",trav,trav->data);
trav = trav->next;
}
}
}
//***********Function to Insert at beginning*********//
struct node *insert_first(struct node *head,int input) {
temp = (struct node *)malloc(sizeof(struct node));
temp->data = input;
printf("\nEntering insert first");
if (head == NULL) {
head = temp;
head->next = NULL;
}
else {
temp->next = head;
head = temp;
}
return head;
}
//**************Function to Insert at End******************//
struct node *insert_last(struct node *head,int input) {
struct node *temp1,*trav;
temp1 = (struct node *)malloc(sizeof(struct node));
trav = (struct node *)malloc(sizeof(struct node));
if (temp1 != NULL) {
temp1->data = input;
}
else {
printf("empty");
}
printf("\nEntering insert last");
if (head == NULL) {
head = temp1;
head->next = NULL;
}
else {
trav = head;
while (trav != NULL) {
trav = trav->next;
}
trav->next = temp1;
}
return head;
}
//*************Main Fucntion***********//
int main() {
int choice,value;
head = NULL;
while(1) {
printf("\n******Please Enter your choice****\n1. To insert at beginning\n2. To insert at End\n3. To Insert middle\n4. To delete\n5. To display\n0. To Exit\n");
scanf("%d",&choice);
switch(choice){
case 1:
printf("Please Enter the value to be added\n");
scanf("%d",&value);
head = insert_first(head,value);
break;
case 2:
printf("Please Enter the value to be added\n");
scanf("%d",&value);
head = insert_last(head,value);
break;
case 5:
display(head);
break;
case 0:
return 0;
default:
printf("Thats a wrong choice\n");
break;
}
}
}
This is the problematic block.
else {
trav = head;
while (trav != NULL) {
trav = trav->next;
}
trav->next = temp1;
When you come out of the while loop trav is NULL. That makes the line
trav->next = temp1;
fail with segmentation violation.
Change that block to:
else {
trav = head;
while (trav->next != NULL) {
trav = trav->next;
}
trav->next = temp1;

How to free node after deletion in linklist in C

I have a very basic doubt. I created a linklist using structure and this is my delete code.
void delete(int num)
{
struct node* temp=head;
struct node* prev=head;
if(temp == NULL)
printf("List Empty\n");
else
{
while(temp != NULL)
{
if(temp->value == num)
{
prev=temp->next;
free(temp);
break;
}
else
{
prev=temp;
temp=temp->next;
}
}
After running this code, the node is not getting deleted. If I print temp->value after free(temp), the value is 0. But this should not be the case. The free should wipe the node. So I don't understand from where the 0 appears. Any idea what is wrong with this code ?
My show function:
void show()
{
struct node *temp = head;
while(temp != NULL)
{
printf("---- %d ---- ", temp->value);
temp=temp->next;
}
printf("\n\n");
}
My struct:
struct node
{
int value;
int pos;
struct node* next;
};
Thanks.
When you find the node in delete:
if(temp->value == num)
{
prev=temp->next;
free(temp);
break;
}
You don't actually make the previous nodes next-pointer point to the nodes next link.
Instead you should do e.g.
prev->next = temp->next;

Resources