I recently wrote a fairly simple piece of code attempting to implement a Binary Search Tree in C with insertion, search, deletion and display operations. Unfortunately, the code does not seem to work.
#include <stdio.h>
#include <stdlib.h>
struct TreeNode {
int data;
struct TreeNode *leftChildNode;
struct TreeNode *rightChildNode;
};
typedef struct TreeNode node;
node *rootNode = NULL;
void insertNode(int i, node *n) {
if(n == NULL) {
n = (node*)malloc(sizeof(node));
n->leftChildNode = NULL;
n->rightChildNode = NULL;
n->data = i;
}
else
if(n->data == i)
printf("\nThis value already exists in the tree!");
else
if(i > n->data)
insertNode(i, n->rightChildNode);
else
insertNode(i, n->leftChildNode);
}
void searchNode(int i, node *n) {
if(n == NULL)
printf("\nValue does not exist in tree!");
else
if(n->data == i)
printf("\nValue found!");
else
if(i > n->data)
searchNode(i, n->rightChildNode);
else
searchNode(i, n->leftChildNode);
}
void deleteNode(int i, node *n) {
if(n == NULL)
printf("\nValue does not exist in tree!");
else
if(n->data == i) {
if(n->leftChildNode == NULL)
n = n->rightChildNode;
else
if(n->rightChildNode == NULL)
n = n->leftChildNode;
else {
node *temp = n->rightChildNode;
while(temp->leftChildNode != NULL)
temp = temp->leftChildNode;
n = temp;
}
}
else
if(i > n->data)
deleteNode(i, n->rightChildNode);
else
deleteNode(i, n->leftChildNode);
}
void displayPreOrder(node *n) {
if(n != NULL) {
printf("%d ", n->data);
displayPreOrder(n->leftChildNode);
displayPreOrder(n->rightChildNode);
}
}
void displayPostOrder(node *n) {
if(n != NULL) {
displayPostOrder(n->leftChildNode);
displayPostOrder(n->rightChildNode);
printf("%d ", n->data);
}
}
void displayInOrder(node *n) {
if(n != NULL) {
displayInOrder(n->leftChildNode);
printf("%d ", n->data);
displayInOrder(n->rightChildNode);
}
}
int main(void) {
int ch, num, num1;
do {
printf("\nSelect a choice from the menu below.");
printf("\n1. Insert a node.");
printf("\n2. Search for a node.");
printf("\n3. Delete a node.");
printf("\n4. Display the Binary Search Tree.");
printf("\nChoice: ");
scanf("%d", &ch);
switch(ch) {
case 1: printf("\nEnter an element: ");
scanf("%d", &num);
//printf("YESYES");
insertNode(num, rootNode);
break;
case 2: printf("\nEnter the element to be searched for: ");
scanf("%d", &num);
searchNode(num, rootNode);
break;
case 3: printf("\nEnter the element to be deleted: ");
scanf("%d", &num);
deleteNode(num, rootNode);
break;
case 4: printf("\nSelect an order for the elements to be display in.");
printf("\n1. Pre-order.");
printf("\n2. Post-order.");
printf("\n3. In-order.");
printf("\nChoice: ");
scanf("%d", &num1);
switch(num1) {
case 1: printf("\nPre-order Display: ");
displayPreOrder(rootNode);
break;
case 2: printf("\nPost-order Display: ");
displayPostOrder(rootNode);
break;
case 3: printf("\nIn-order Display: ");
displayInOrder(rootNode);
break;
default: exit(0);
}
break;
default: exit(0);
}
//printf("%d", rootNode->data);
printf("\nIf you want to return to the menu, press 1.");
printf("\nChoice: ");
scanf("%d", &num);
} while(num == 1);
return 0;
}
In fact, notice the commented line printf("%d", rootNode->data);
just before the do-while
block in main()
ends. If I uncomment this line, compile the program and run it, the program throws a segmentation fault. Could anyone tell me why this error is occurring and why the code as a whole isn't running? Thanks in advance.
Insertion in Binary Search treeTo insert an element in BST, we have to start searching from the root node; if the node to be inserted is less than the root node, then search for an empty location in the left subtree. Else, search for the empty location in the right subtree and insert the data.
Binary Tree Implementationif the new node's value is lower than the current node's, go to the left child. if the new node's value is greater than the current node's, go to the right child. when the current node is null, we've reached a leaf node, we insert the new node in that position.
A Binary Search Tree (BST) is a tree in which all the nodes follow the below-mentioned properties − The value of the key of the left sub-tree is less than the value of its parent (root) node's key. The value of the key of the right sub-tree is greater than or equal to the value of its parent (root) node's key.
You have a misconception about the way C handles arguments. In C, all arguments are passed by value, including pointers. When you reassign a pointer inside of a function you are reassigning a copy of that pointer.
For instance:
void f ( int *p );
int *p;
f(p);
The address (&p
) of the pointer is different in the function. They both point to the same location (have the same value), but each has a different address. When you assign the pointer to the return value of malloc
, it is only assigning the function local copy of that pointer.
One way to fix this is to introduce another level of indirection, and pass the address of the pointer: void insertNode(int i, node **n)
, which you can call like insertNode(0, &n)
. When you want to change it to something else, dereference it once and then assign: *p = malloc(sizeof(node))
.
Another solution is to have the function return the pointer and assign it in the calling code: return malloc(sizeof(node))
. (Note: You would actually return it after the initialization code... also don't cast the return value of malloc
in C).
At the top, you declare
node *rootNode = NULL;
If you don't run insertNode
(successfully - See Matt's answer), the node will still be NULL when trying to print it and that's why you're getting the segfault.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With