Insert element into a BST in C - c

I've got a structure type like the following:
typedef struct TreeNode{
int val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
To add an element to my
TreeNode* insert(TreeNode *root, int val){
TreeNode* a;
a = root;
int i;
if(a==NULL){
a -> val = val;
a -> left = NULL;
a -> right = NULL;
}
else if(a->val < val){
return insert(root->left,val);
}
else if(a->val > val)
return insert(root->right,val);
}
This gives no output when i evaluate it. What is my fault?

In the a == NULL case, you need to allocate memory for the node. Otherwise a -> val is illegal.
Also need to add a return to the code. You can return (a). Then when you call the function, you call it as root = insert(root, val)
The code is below.
TreeNode* insert(TreeNode *root, int val){
TreeNode* a;
a = root;
int i;
if(a==NULL){
// Allocate memory here
a = malloc(sizeof (root));
if (a== NULL)
{
// Malloc error, You can exit the program or print a debug message here
}
a -> val = val;
a -> left = NULL;
a -> right = NULL;
}
else if(a->val < val){
return insert(root->left,val);
}
else if(a->val > val)
return insert(root->right,val);
return a;
}

Related

segmentation fault 11 in c binary search tree

I am getting a segmentation fault when trying to print the nodes in my binary tree. It looks to be an issue with the third node. I have searched google and stack overflow for hours but I can not understand what the problem is. I am trying to teach myself data structures in C and am very much a novice so I may be doing something in a frowned upon way.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *left;
struct node *right;
} Node;
typedef struct
{
Node *root;
} BinarySearchTree;
void printInOrder(Node *);
void addNode(Node *, Node *);
int main (void)
{
BinarySearchTree tree;
BinarySearchTree *tree_ptr = &tree;
Node n1, n2, n3;
n1.data = 1;
n2.data = 2;
n3.data = 3;
Node *n1_ptr = &n1;
Node *n2_ptr = &n2;
Node *n3_ptr = &n3;
tree_ptr->root = n1_ptr;
addNode(tree_ptr->root, n2_ptr);
addNode(tree_ptr->root, n3_ptr);
printInOrder(tree_ptr->root);
}
void printInOrder(Node *root)
{
if (root == NULL)
{
return;
} else
{
printInOrder(root->left);
printf("%i\n", root->data);
printInOrder(root->right);
}
}
void addNode(Node *root, Node *node)
{
if (node->data < root->data)
{
if (root->left == NULL)
{
root->left = node;
} else
{
addNode(root->left, node);
}
}
else if (node->data > root->data)
{
if (root->right == NULL)
{
root->right = node;
} else
{
addNode(root->right, node);
}
}
}
output:
1
2
Segmentation fault: 11
There doesn't seem to be an issue with any but the third node. If I comment out the line that adds the second node I get the same error (with only 1 being printed, obviously).
Your initialization is incomplete
n1.data = 1;
n2.data = 2;
n3.data = 3;
should also set the pointers
n1.data = 1;
n1.left = NULL;
n1.right = NULL;
n2.data = 2;
n2.left = NULL;
n2.right = NULL;
n3.data = 3;
n3.left = NULL;
n3.right = NULL;
Problem is occurring because you are not initializing all the member of structure Node type variable.
I would suggest, you should write a function to initialize the Node type variable, like this:
void init_node(Node * nodeptr, int data)
{
nodeptr->data = data;
nodeptr->left = NULL;
nodeptr->right = NULL;
}
and in your main() (or from where ever you want to initialize) you can simply do:
init_node(&n1, 1);
init_node(&n2, 2);
init_node(&n3, 3);
With this, you will never miss assigning NULL to left and right pointer during initialization of Node type variable and chances of the error occurring because of it will be reduced to a greater extent.

Having trouble understanding this function return

I am working with the following code I found on here to begin my project that involves a tree data structure.
struct node{
int ID;
struct node* next;
struct node* child;
};
typedef struct node node;
node* new_node(int);
node* add_sibling(node*, int);
node* add_child(node*, int);
int main()
{
int i;
node *root = new_node(0);
for (i = 1; i <= 3; i++)
add_child(root, i);
}
node * new_node(int ID)
{
node* new_node =(node*) malloc(sizeof(node));
if (new_node) {
new_node->next = NULL;
new_node->child = NULL;
new_node->ID = ID;
}
return new_node;
}
node* add_sibling(node* n, int ID)
{
if (n == NULL)
return NULL;
while (n->next)
n = n->next;
return (n->next = new_node(ID));
}
node* add_child(node* n, int ID)
{
if (n == NULL)
return NULL;
if (n->child)
return add_sibling(n->child, ID);
else
return (n->child = new_node(ID));
}
I am a beginner with C/C++ and programming in general. I think I understand everything about the code except for the add_child function. The function seems to return a pointer to a node, but when it is called in main, it seems to be called as though it were a void function. I would have thought to call the function this way
*root = add_child(root,i);
like how new_node is called, or to write add_child as a void function, but both of these modifications results in errors (not to mention the implementation in the code I found does work). What am I missing?
This function rewritten will look like following.
node* add_child(node* n, int ID)
{
// For null pointer return null
if (n == NULL)
{
return NULL;
}
// If element has child add a sibling to that child
if (n->child)
{
node* sibling_for_child = add_sibling(n->child, ID);
return sibling_for_child;
}
else
{
// Otherwise just add element as a child
node* child_node = new_node(ID);
n->child = child_node;
return child_node;
}
}
The result of assignment is an assigned value(*) like in this chaining assignment:
int a, b;
a = b = 3;
which is actually:
a = (b = 3);
or
b = 3;
a = b;

Function gets right pointer but returns NULL

I'm creating a binary tree in C in which I use indexes as in a binary search tree. I'm having trouble with a function that finds a node.
My code for the tree is in a separate file and it's the following:
struct node {
struct node *left;
struct node *right;
int index;
void *data;
};
struct node * init_mt()
{
struct node *root = malloc(sizeof(struct node));
root->index = -1;
root->data = NULL;
root->left = root->right = NULL;
return root;
}
void create_mt(struct node *mt, int h, int i)
{
if (h == 0) // end of tree reached
{
mt->index = 0;
mt->left = mt->right = NULL;
return;
}
else
{
mt->index = i;
int l = i-pow(2,h-1);
int r = i+pow(2,h-1);
mt->left = malloc(sizeof(struct node));
mt->right = malloc(sizeof(struct node));
create_mt(mt->left,h-1,l);
create_mt(mt->right,h-1,r);
}
}
struct node * get_node_mt(struct node *mt, int p, int h)
{
if (h == -1) // end of tree reached
{
return NULL;
}
else
{
if (mt->index == p)
{
printf("Found %p\n", mt);
return mt;
}
else if (mt->index > p)
{
get_node_mt(mt->left,p,h-1);
}
else
{
get_node_mt(mt->right,p,h-1);
}
}
}
When I run my main like this (root->left->left is the node index #2):
struct node *root = NULL;
root = init_mt();
create_mt(root,3,8); // root index == 8
printf("%d %p\n", root->left->left->index,root->left->left);
struct node *find;
find = get_node_mt(root,2,3);
printf("%p\n", find);
I get the following output:
2 0x7ffd1dd011a0
Found 0x7ffd1dd011a0
0x0
I don't understand why I get the right pointer both when priting directly using root->left->left and inside the function get_node_mt() but not when I print the pointer I've returned. What am I doing wrong?
The get_node_mt() function calls itself in two places. Neither of these two places return a value.
struct node * get_node_mt(struct node *mt, int p, int h)
{
if (h == -1) // end of tree reached
return NULL;
else if (mt->index == p)
return mt;
else if (mt->index > p)
get_node_mt(mt->left,p,h-1);
else
get_node_mt(mt->right,p,h-1);
}
I reformatted the code a bit and removed a lot of braces. The compiler should've warned about this problem, IMHO.

error in function that counts the number of times an int appears in a list

I'm trying to count the number of times a given int occurs in a list, but I'm having a difficult time getting my pointers to work. Can someone spot where is my logic failing? Is it because of how I'm implementing the "follows" "->" in the counting function?
//this is in my .h file
typedef struct list_struct LIST;
///// the rest is in my .c file
typedef struct node {
ElemType val;
struct node *next;
} NODE;
struct list_struct {
NODE *front;
NODE *back;
};
//this is my counting function
int lst_count(LIST *l, ElemType x) {
LIST *current = l;
int count = 0;
while (current != NULL) {
if ((current->front->val) == x) count++;
current = current->front->next;
//in the line above I get the following warning:
//"incompatible pointer types assigning to 'LIST*' (aka 'struct list_struct*') from 'struct node*'"
}
return count;
}
Your problem is in the while loop
You are in a list struct, then you do
current->front->next;
Now you are in a NODE type struct, in the next iteration there is no front in NODE.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
struct node *previous;
} NODE;
int lst_count(NODE *l, int x) {
NODE *current = l;
NODE *start = current; /* so that we wont loose the start*/
int count = 0;
while (current != NULL) {
if ((current->val) == x)
count++;
current = current->next;
}
return count;
}
int main()
{
NODE* p = (NODE*)malloc(sizeof(NODE));
NODE* p1 = (NODE*)malloc(sizeof(NODE));
NODE* p2 = (NODE*)malloc(sizeof(NODE));
NODE* start = p;
p->val = 5;
p->next = p1;
p1->next = p2;
p2->next=NULL;
p1->val = 5;
p2->val = 5;
printf("%d", lst_count(start, 5));
}
I got the function to work thanks to your all advises
int lst_count(LIST *l, int x) {
NODE *current = l->front;
int count = 0;
while (current != NULL) {
if ((current->val) == x) count++;
current = current->next;
}
return count;
}

Segmentation Fault (core dumped) in C in Delete() function

i am writing a Dictionary using linked list in C, and all my functions work except my delete function, which is shown below along with all other necessary code. Every time i try to run my program as soon as it reaches a line in which it must delete a node, it gives me the error: Segmentation Fault (core dumped) which means it has something to do with the memory allocation or a null pointer i think. I know that the rest of my code works. All and any help is appreciated! :)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
#include"Dictionary.h"
// NodeObj
typedef struct NodeObj{
char* key;
char* value;
struct NodeObj* next;
} NodeObj;
// Node
typedef NodeObj* Node;
// newNode()
// constructor of the Node type
Node newNode(char* key, char* value)
{
Node N = malloc(sizeof(NodeObj));
assert(N!=NULL);
// if(key!=NULL && value!=NULL){
N->key = key;
N->value = value;
N->next = NULL;
// }
return(N);
}
// DictionaryObj
typedef struct DictionaryObj{
Node head;
int numItems;
} DictionaryObj;
// newDictionary()
// constructor for the Dictionary type
Dictionary newDictionary(void){
Dictionary D = malloc(sizeof(DictionaryObj));
assert(D!=NULL);
D->head = NULL;
D->numItems = 0;
return D;
}
Node findKey(Dictionary D, char*key){
Node N;
N = D->head;
while(N != NULL){
if(strcmp(N->key,key)==0){
return N;
}
N = N->next;
}
return NULL;
}
char* lookup(Dictionary D, char* k){
if(findKey(D, k)==NULL){
return NULL;
}else{
Node N;
N = findKey(D, k);
return N->value;
}
}
void delete(Dictionary D, char* k)
{
if(lookup(D,k) == NULL){
fprintf(stderr,
"KeyNotFoundException: Cannot delete non-existent key\n");
exit(EXIT_FAILURE);
}
int check = strcmp(D->head->key, k);
if(check == 1){
D->head = D->head->next;
return;
}
Node cur;
Node prev;
cur = D->head;
prev = NULL;
while( cur != NULL){
int ret1;
ret1 = strcmp(cur->key, k);
while( ret1 == 0){
prev = cur;
cur = cur->next;
}
}
prev->next = cur->next;
D->numItems--;
}
The NodeObject should store copy of the string and care for deleting it:
typedef struct Node Node;
struct Node {
Node *next;
char *key, *value;
};
Node* newNode(char* key, char* value) {
assert(key && value);
Node* node = (Node*)malloc(sizeof(Node));
assert(node);
node->next = NULL;
node->key = strdup(key);
node->value = strdup(value);
}
void delNode(Node* node) {
free(node->key);
free(node->value);
}
Consider using the original code (without that strdup) in this scenairo:
Node* prepare() {
char key_buf[20]; strcpy(key_buf, "mykey");
char val_buf[20]; strcpy(val_buf, "myval");
return newNode(key_buf, val_buf);
}
void examine(Node* node) {
printf("Node key=%s value=%s\n", node->key, node->value);
}
int main() {
examine(prepare());
}
the above code would crash because Node would have pointers to stack (in your case without that strdup), but key_buf+val_buf were only valid inside prepare() (garbage outside and therefore inside examine() - node->key points to random data).

Resources