Insertion failure in a Binary Search Tree - c

Here is my code for the creation and insertion of the binary search tree
struct BTNode
{
int info;
struct BTNode *left, *right;
};
struct BTNode* create(int data)
{
struct BTNode *root;
struct BTNode *n = malloc(sizeof(struct BTNode));
n->info = data;
n->left = NULL;
n->right = NULL;
root = n;
return(root);
}
struct BTNode* insert(struct BTNode *root, int data)
{
struct BTNode *ptr;
struct BTNode *n = malloc(sizeof(struct BTNode));
if (n == NULL)
printf("\nOUT OF MEMORY!\n");
n->info = data;
n->left = NULL;
n->right = NULL;
ptr = root;
while (ptr != NULL){
if (data < ptr->info){
if (ptr->left == NULL)
ptr->left = n;
ptr = ptr->left;
}
else if (data > ptr->info){
if (ptr->right == NULL)
ptr->right = n;
ptr = ptr->right;
}
}
return(n);
}
and here is the main() function
int main()
{
struct BTNode *root = NULL;
int choice, data;
printf("\nWrite the root data: ");
scanf("%d", &data);
root = create(data);
while (1){
printf("\n1.Insert 2.Preorder 3.Exit\n");
scanf("%d", &choice);
switch(choice){
case 1:
printf("\nWrite the data: ");
scanf("%d", &data);
insert(root, data);
break;
I am able to create the root node but whenever I am trying to insert the data, I give my data and the compiler stops doing anything. Any idea why this is happening?

Your while() loop goes on forever because you keep going even after you find a place to insert the node:
while(ptr!=NULL){
if(data<ptr->info){
if(ptr->left==NULL)
ptr->left=n;
ptr=ptr->left;
}
else if(data>ptr->info){
if(ptr->right==NULL)
ptr->right=n;
ptr=ptr->right;
}
}
You need to break out of the while() loop after inserting the node:
while (ptr != NULL) {
if (data < ptr->info) {
if (ptr->left == NULL) {
ptr->left = n;
break;
}
ptr = ptr->left;
} else if (data > ptr->info) {
if (ptr->right == NULL) {
ptr->right = n;
break;
}
ptr = ptr->right;
}
}
Also, bonus points for checking if malloc() fails
struct BTNode *n = malloc(sizeof(struct BTNode));
if (n == NULL)
printf("\nOUT OF MEMORY!\n");
But negative points for simply continuing on anyway, you should exit the function if malloc() fails
struct BTNode *n = malloc(sizeof(struct BTNode));
if (n == NULL) {
printf("\nOUT OF MEMORY!\n");
return NULL:
}
And then of course, the code calling insert() should know what to do if insert() returns NULL.

Related

How to prevent the program to display the converted input, I'm wanting the program to display the original input

I want my code to display the original input 3 -> 2-> 1-> and not display the reversed one.
The output is displaying the 1-> 2-> 3-> . I want to see the original input without ruining the codes. How can I do that? Our professor taught us the concept of linked list and it is connected in this program to input a number and check if it is a palendrome
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
void insertNum(struct node** head, int number) {
struct node* temp = malloc(sizeof(struct node));
temp -> data = number;
temp -> next = *head;
*head = temp;
}
void display(struct node* head) {
struct node* printNode = head;
printf("displaying list1...\n");
printf("displaying the converted list..\n");
while (printNode != NULL) {
if (printNode->next)
printf("%d->",printNode->data);
else
printf("%d->NULL\n",printNode->data);
printNode=printNode->next;
}
}
struct node* reverseLL(struct node* head) {
struct node* reverseNode = NULL, *temp;
if (head == NULL) {
printf("\nThe list is empty.\n\n");
exit(0);
}
while (head != NULL) {
temp = (struct node*) malloc(sizeof(struct node));
temp -> data = head -> data;
temp -> next = reverseNode;
reverseNode = temp;
head = head -> next;
}
return reverseNode;
}
int check(struct node* LLOne, struct node* LLTwo) {
while (LLOne != NULL && LLTwo != NULL) {
if (LLOne->data != LLTwo->data)
return 0;
LLOne = LLOne->next;
LLTwo = LLTwo->next;
}
return (LLOne == NULL && LLTwo == NULL);
}
void deleteList(struct node** display) {
struct node* temp = *display;
while (temp != NULL) {
temp = temp->next;
free(*display);
*display = temp;
}
}
int main() {
int inputNum, countRun = 0, loop;
char choice;
struct node* reverseList;
struct node* head = NULL;
do {
printf("%Run number : %d\n", ++countRun);
printf("Enter 0 to stop building the list, else enter any integer\n");
printf("Enter list to check whether it is a palindrome... \n");
do {
scanf("%d", &inputNum);
if (inputNum == 0)
break;
insertNum(&head, inputNum);
} while (inputNum != 0);
display(head);
reverseList = reverseLL(head);
if ((check(head, reverseList)) == 1)
printf("\nPalindrome list.\n\n");
else
printf("\nNot palindrome.\n\n");
deleteList(&head);
} while (countRun != 2);
system("pause");
return 0;
}
Your insertNum inserts at the front of the list.
You need a version that appends at the back of the list:
void
appendNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
struct node *cur;
struct node *prev;
temp->data = number;
// find tail of the list
prev = NULL;
for (cur = *head; cur != NULL; cur = cur->next)
prev = cur;
// append after the tail
if (prev != NULL)
prev->next = temp;
// insert at front (first time only)
else
*head = temp;
}
Here is the full code:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
void
appendNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
struct node *cur;
struct node *prev;
temp->data = number;
// find tail of the list
prev = NULL;
for (cur = *head; cur != NULL; cur = cur->next)
prev = cur;
// append after the tail
if (prev != NULL)
prev->next = temp;
// insert at front (first time only)
else
*head = temp;
}
void
insertNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
temp->data = number;
temp->next = *head;
*head = temp;
}
void
display(struct node *head)
{
struct node *printNode = head;
printf("displaying list1...\n");
printf("displaying the converted list..\n");
while (printNode != NULL) {
if (printNode->next)
printf("%d->", printNode->data);
else
printf("%d->NULL\n", printNode->data);
printNode = printNode->next;
}
}
struct node *
reverseLL(struct node *head)
{
struct node *reverseNode = NULL,
*temp;
if (head == NULL) {
printf("\nThe list is empty.\n\n");
exit(0);
}
while (head != NULL) {
temp = (struct node *) malloc(sizeof(struct node));
temp->data = head->data;
temp->next = reverseNode;
reverseNode = temp;
head = head->next;
}
return reverseNode;
}
int
check(struct node *LLOne, struct node *LLTwo)
{
while (LLOne != NULL && LLTwo != NULL) {
if (LLOne->data != LLTwo->data)
return 0;
LLOne = LLOne->next;
LLTwo = LLTwo->next;
}
return (LLOne == NULL && LLTwo == NULL);
}
void
deleteList(struct node **display)
{
struct node *temp = *display;
while (temp != NULL) {
temp = temp->next;
free(*display);
*display = temp;
}
}
int
main()
{
int inputNum, countRun = 0, loop;
char choice;
struct node *reverseList;
struct node *head = NULL;
do {
printf("%Run number : %d\n", ++countRun);
printf("Enter 0 to stop building the list, else enter any integer\n");
printf("Enter list to check whether it is a palindrome... \n");
do {
scanf("%d", &inputNum);
if (inputNum == 0)
break;
#if 0
insertNum(&head, inputNum);
#else
appendNum(&head, inputNum);
#endif
} while (inputNum != 0);
display(head);
reverseList = reverseLL(head);
if ((check(head, reverseList)) == 1)
printf("\nPalindrome list.\n\n");
else
printf("\nNot palindrome.\n\n");
deleteList(&head);
} while (countRun != 2);
system("pause");
return 0;
}

Deletion of node in Binary Search Tree is throwing error

Experts, this is my code of creation and deletion of nodes in Binary Search Tree. It's working fine for insertion, but throwing segmentation fault (core dumped) when trying to delete a node (on invoking deleteNode( ) function). I don't understand what's actually the problem. Please help! Thank you in advance!
#include <stdio.h>
#include <stdlib.h>
int size = 0;
typedef struct mylist{
int data;
struct mylist *left;
struct mylist *right;
}node;
node *root;
void create_root(node *root){
root = NULL;
}
//Inserting nodes
node* insert(node *root, int val){
node *ptr, *parentptr, *nodeptr;
ptr = (node*)malloc(sizeof(node));
ptr -> data = val;
ptr -> left = NULL;
ptr -> right = NULL;
if(root == NULL)
root = ptr;
else{
parentptr = NULL;
nodeptr = root;
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;
}
return root;
}
node* minValueNode(node* root)
{
node* cur = root;
while (cur->left != NULL)
cur = cur->left;
return cur;
}
node* deleteNode(node* root, int key)
{
if (root == NULL){
printf("\nValue not found\n");
}
if (key < root-> data)
root->left = deleteNode(root->left, key);
else if (key > root-> data)
root->right = deleteNode(root->right, key);
else
{
if (root->left == NULL)
{
node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
node *temp = root->left;
free(root);
return temp;
}
node* temp = minValueNode(root->right); //Inorder successor
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
return root;
}
void main(){
int option, val;
node *ptr;
int flag = 1;
create_root(root);
while(flag != 2){
printf("\nChoose-\n1-Insert\n2-Delete\n3-Exit\n");
scanf("%d", &option);
switch(option){
case 1:{
printf("\nEnter the value of new node\n");
size++;
scanf("%d", &val);
root = insert(root, val);
break;
}
case 2:{
int k;
printf("Enter the value to delete");
scanf("%d",&k);
root=deleteNode(root, k);
size--;
break;
}
case 3:
flag=2;
break;
default:
printf("\nWrong entry\n");
}
}
}
You must either return NULL in the first if() in deleteNode(), or you must put an else before the second if()
node* deleteNode(node* root, int key)
{
if (root == NULL){
printf("\nValue not found\n");
return NULL; // <== This was missing.
}
...
}
or alternatively (perhaps intended?):
node* deleteNode(node* root, int key)
{
if (root == NULL){
printf("\nValue not found\n");
}
else if(key < root->data)
...
}
At the moment this falls through to the next if(key < root->data) even when root is null, which causes the segfault.
Also: Use nullptr if you can use C++11.

segmenation fault error in my linkedList -C

I put together a few pieces of code to make a linked list that adds to head(Has a special function) and in the middle(also special function).
my problem is, i need to provide the program with numbers and insert them as nodes in my LINKEDLIST. However, my display function(to display the tree of nodes) gives back segmentation fault and so does just taking values in without any display function.
I'm fairly new to malloc so i suspect the problem is there?
Thanks
#include<stdio.h>
#include<stdlib.h>
/*LINKEDLIST STRUCT*/
struct node {
int data;
struct node *next;
};
/*Inserting head-Node*/
struct node *insert_head(struct node *head, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = head;
head = temp;
return head;
}
/*Inserting inside a list*/
void after_me(struct node *me, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = me->next;
me->next = temp;
}
/*PRINTING LIST*/
void display(struct node *head)
{
struct node *moving_ptr = head;
while(moving_ptr != NULL)
{
printf("%d-->",moving_ptr->data);
moving_ptr = moving_ptr->next;
}
}
int main()
{
int index;
struct node *head;
struct node *previous_node;
scanf("%d", &index);
while(index > 0)
{
/*allocating in List */
if(head == NULL)
head = insert_head(head,index);
else
if((head != NULL) && (index <= (head->data)))
{
struct node *temp;
head->next = temp;
temp->next = head;/*TRY INSERT HEAD FUNC.*/
}
else
if((head != NULL) && (index > (head->data)))
{
previous_node->data = index-1;
after_me(previous_node,index);
}
scanf("%d", &index);
}
display(head);
}
I suggest as follows.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
//aggregated into one place
struct node *new_node(int number){
struct node *temp;
if(NULL == (temp = malloc(sizeof(*temp)))){
printf("\nNot enough memory\n");
exit(1);
}
temp->data = number;
temp->next = NULL;
return temp;
}
struct node *insert_head(struct node *head, int number) {
struct node *temp = new_node(number);
temp->next = head;
return temp;
}
void after_me(struct node *me, int number){
struct node *temp = new_node(number);
temp->next = me->next;
me->next = temp;
}
void display(struct node *head){
struct node *moving_ptr = head;
while(moving_ptr != NULL){
printf("%d", moving_ptr->data);
if(moving_ptr = moving_ptr->next)
printf("-->");
}
putchar('\n');
}
struct node *insert(struct node *me, int number){
if(me){
if(number <= me->data){
me = insert_head(me, number);
} else {
me->next = insert(me->next, number);
}
} else {
me = new_node(number);
}
return me;
}
void release(struct node *list){//Of course, you will be able to replace a simple loop(e.g while-loop).
if(list){
release(list->next);
free(list);
}
}
int main(void){
struct node *head = NULL;
int index;
while(1==scanf("%d", &index) && index > 0){
head = insert(head, index);
}
display(head);
release(head);
return 0;
}

Linked list add() method in C

Where is error the following code?
addNode() function is not run, neither is the traverse() function.
Last data is not shown.
#include <stdio.h>
#include <stdlib.h>
struct isimler{
char isim[10];
struct isimler *next;
};
typedef struct isimler node;
node *head;
void createList(){
int k, n;
node *po;
printf("Eleman Sayisi: "); scanf("%d", &n);
for(k = 0; k<n; k++){
if(k == 0){
head = (node *) malloc(sizeof(node));
po = head;
}else{
po->next = (node *) malloc(sizeof(node));
po = po->next;
}
printf("Isim Girin: "); scanf("%s",po->isim);
}
po->next = NULL;
}
void addNode(){
node *po, *newNode;
po = head;
while(po != NULL){
po = po->next;
}
po = (node *) malloc(sizeof(node));
printf("Isim Girin: "); scanf("%s", po->isim);
po->next = NULL;
}
void traverseList(){
node *po;
int i=0;
po = head;
while(po != NULL){
printf("%d.\t%s\n",i,po->isim);
po = po->next;
i++;
}
}
int main(){
createList();
traverseList();
addNode();
traverseList();
return 1903;
}
Your current addNode() method creates a new node but it doesn't add it to your linked list.
You need to modify your addNode() method like so:
void addNode(){
node *po, *newNode;
po = head;
while(po->next != NULL) { // change this so you don't lose the end of the list
po = po->next; // po is now pointing to the last node in the list
}
newNode = (node *) malloc(sizeof(node)); // change this to newNode
printf("Isim Girin: "); scanf("%s", newNode->isim);
po->next = newNode; // add the new node here, don't set it to NULL
newNode->next = NULL;
}
You can have look this code and get to know where exactly you are having problem
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
struct test_struct
{
int val;
struct test_struct *next;
};
struct test_struct *head = NULL;
struct test_struct *curr = NULL;
struct test_struct* create_list(int val)
{
printf("\n creating list with headnode as [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
head = curr = ptr;
return ptr;
}
struct test_struct* add_to_list(int val, bool add_to_end)
{
if(NULL == head)
{
return (create_list(val));
}
if(add_to_end)
printf("\n Adding node to end of list with value [%d]\n",val);
else
printf("\n Adding node to beginning of list with value [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
if(add_to_end)
{
curr->next = ptr;
curr = ptr;
}
else
{
ptr->next = head;
head = ptr;
}
return ptr;
}
struct test_struct* search_in_list(int val, struct test_struct **prev)
{
struct test_struct *ptr = head;
struct test_struct *tmp = NULL;
bool found = false;
printf("\n Searching the list for value [%d] \n",val);
while(ptr != NULL)
{
if(ptr->val == val)
{
found = true;
break;
}
else
{
tmp = ptr;
ptr = ptr->next;
}
}
if(true == found)
{
if(prev)
*prev = tmp;
return ptr;
}
else
{
return NULL;
}
}
int delete_from_list(int val)
{
struct test_struct *prev = NULL;
struct test_struct *del = NULL;
printf("\n Deleting value [%d] from list\n",val);
del = search_in_list(val,&prev);
if(del == NULL)
{
return -1;
}
else
{
if(prev != NULL)
prev->next = del->next;
if(del == curr)
{
curr = prev;
}
else if(del == head)
{
head = del->next;
}
}
free(del);
del = NULL;
return 0;
}
void print_list(void)
{
struct test_struct *ptr = head;
printf("\n -------Printing list Start------- \n");
while(ptr != NULL)
{
printf("\n [%d] \n",ptr->val);
ptr = ptr->next;
}
printf("\n -------Printing list End------- \n");
return;
}
int main(void)
{
int i = 0, ret = 0;
struct test_struct *ptr = NULL;
print_list();
for(i = 5; i<10; i++)
add_to_list(i,true);
print_list();
for(i = 4; i>0; i--)
add_to_list(i,false);
print_list();
for(i = 1; i<10; i += 4)
{
ptr = search_in_list(i, NULL);
if(NULL == ptr)
{
printf("\n Search [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n Search passed [val = %d]\n",ptr->val);
}
print_list();
ret = delete_from_list(i);
if(ret != 0)
{
printf("\n delete [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n delete [val = %d] passed \n",i);
}
print_list();
}
return 0;
}

Implementation of Stacks using Linked List. Where am I going wrong?

This is the code I've written in C :
#include<stdio.h>
struct Node
{
int info;
struct Node *next;
};
void init_Node(struct Node *n)
{
n->next = NULL;
}
struct Node *front = NULL;
void display()
{
struct Node *rear = front;
if(rear == NULL)
printf("List is empty!\n");
else
{
printf("[%i]-->",rear->info);
rear = rear->next;
}
printf("NULL");
printf("\n");
}
void addEnd(int x)
{
struct Node *n = malloc(sizeof(struct Node));
struct Node *rear = front;
n->info = x;
if(front == NULL)
front = n;
else
{
while(rear->next != NULL)
rear = rear->next;
rear->next = n;
rear = n;
}
display();
}
void deleteEnd()
{
struct Node *rear = front;
if(front == NULL)
printf("Stack is Empty!");
else
{
while(rear->next->next != NULL)
{
rear = rear->next;
}
printf("Popped : %i\n", rear->next->info);
rear->next = NULL;
display();
}
}
int main()
{
struct Node *n = malloc(sizeof(struct Node));
init_Node(n);
clrscr();
addEnd(23);
addEnd(45);
addEnd(8);
addEnd(57);
deleteEnd();
addEnd(98);
deleteEnd();
getch();
return 0;
}
The below output is the output when the implementation was done in C++ using classes.
The output for the program was supposed to be this -
but the output of my code is this -
EDIT
After adding the while() loop and adding n->next = NULL; the output comes out to be :
Where am I going wrong?
You need two changes:
void display()
{
struct Node *rear = front;
if(rear == NULL)
printf("List is empty!\n");
else
{
// CHANGE 1: You need a while loop here
while(rear != NULL) {
printf("[%i]-->",rear->info);
rear = rear->next;
}
}
printf("NULL");
printf("\n");
}
void addEnd(int x)
{
struct Node *n = malloc(sizeof(struct Node));
struct Node *rear = front;
n->info = x;
// CHANGE 2: You need to clear n->next to NULL.
n->next = NULL;
if(front == NULL)
front = n;
else
{
while(rear->next != NULL)
rear = rear->next;
rear->next = n;
rear = n;
}
display();
}
in your function, addEnd() you need to initialize the next pointer to zero. So, right after the line n->info = x; add a line n->next = 0;

Resources