function to delete node in a BST of strings - c

i'm having a problem in this code. its function is to go through a BST of strings and delete the nodes that satisfy some conditions (if in the word in the node there's an instance of the banned character, the node needs to be deleted). the problem is that it seg-faults in scrematurabanned2 because in the last recursive call it tries to access a node that is not existant and seg-faults. how can i fix this?
sorry in advance if there's not a lot of code in this question but this is a huge program and these are the parts that i think are responsible for the problem
struct node {
char *value;
struct node *p_left;
struct node *p_right;
};
int CmpStr(const char *a, const char *b)
{
return (strcmp (a, b));
}
void inserisciInAlbero2(char* key, struct node** leaf, Compare cmp) {
int res;
if( *leaf == NULL ) {
*leaf = (struct node*) malloc(sizeof( struct node ) );
(*leaf)->value = malloc( strlen (key) +1 );
strcpy ((*leaf)->value, key);
(*leaf)->p_left = NULL;
(*leaf)->p_right = NULL;
} else {
res = cmp (key, (*leaf)->value);
if( res < 0)
inserisciInAlbero2( key, &(*leaf)->p_left, cmp);
else if( res > 0)
inserisciInAlbero2( key, &(*leaf)->p_right, cmp);
}
}
void scrematurabanned2(struct node *head, const char *bannedchar, int n){
if( head != NULL ) {
scrematurabanned2(head->p_left, bannedchar, n);
if(strpbrk(head->value,bannedchar)!=NULL)
{
head = deleteNode(head, head->value);
}
scrematurabanned2(head->p_right, bannedchar, n);
}
}
struct node * minValueNode(struct node* node) {
struct node* current = node;
while (current->p_left != NULL)
current = current->p_left;
return current;
}
struct node* deleteNode(struct node* root, char *key) {
if (root == NULL)
return root;
int cmp_result = strcmp(key, root->value);
if (cmp_result < 0)
root->p_left= deleteNode(root->p_left, key);
else if (cmp_result>0)
root->p_right= deleteNode(root->p_right, key);
else{
if (root->p_left==NULL) {
struct node *temp = root->p_right;
free(root);
return temp;
} else if(root->p_right==NULL){
struct node *temp = root->p_left;
free(root);
return temp;
}
struct node* temp = minValueNode(root->p_right);
strcpy(root->value, temp->value);
}
return root;
}
int main() {
struct node *BST = NULL;
inserisciInAlbero2("2rj9R", &BST, (Compare) CmpStr);
inserisciInAlbero2("2rF9d", &BST, (Compare) CmpStr);
inserisciInAlbero2("2rq9R", &BST, (Compare) CmpStr);
inserisciInAlbero2("2ft9R", &BST, (Compare) CmpStr);
scrematurabanned2(BST, 'r', 5));

Related

BST node deletion in c

i'm trying to delete the nodes of a BST of strings that don't have a certain char in a certain position, but the code seg-faults and i can't trace the source of the error.
the inserting phase does the job, it's the deleting part that gives me headaches.
the delete function finds the key in the tree then deletes the node containing that key.
any help?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct BST {
char *value;
struct BST *p_left;
struct BST *p_right;
};
typedef int (*Compare)(const char *, const char *);
int CmpStr(const char *a, const char *b)
{return (strcmp (a, b));}
//function to insert words into string
void insertInTree(char* key, struct BST** leaf, Compare cmp) {
int res;
if( *leaf == NULL ) {
*leaf = (struct BST*) malloc(sizeof( struct BST ) );
(*leaf)->value = malloc( strlen (key) +1 );
strcpy ((*leaf)->value, key);
(*leaf)->p_left = NULL;
(*leaf)->p_right = NULL;
} else {
res = cmp (key, (*leaf)->value);
if( res < 0)
insertInTree(key, &(*leaf)->p_left, cmp);
else if( res > 0)
insertInTree(key, &(*leaf)->p_right, cmp);
}
}
//helper function to find the min value string in alphabetical order
char* minValueNode(struct BST* node) {
struct BST* current = node;
while (current->p_left != NULL)
current = current->p_left;
return current->value;
}
//function to delete the node in the BST
struct BST* deleteNode(struct BST* root, char *key) {
if (root == NULL)
return NULL;
int cmp_result = strcmp(key, root->value);
if (cmp_result < 0)
root->p_right= deleteNode(root->p_right, key);
else if (cmp_result>0)
root->p_left= deleteNode(root->p_left, key);
else{
if (root->p_left == NULL && root->p_right == NULL){
free(root);
return NULL;
}
else if (root->p_left==NULL) {
struct BST *temp = root->p_right;
free(root);
return temp;
} else if(root->p_right==NULL){
struct BST *temp = root->p_left;
free(root);
return temp;
}
else {
char *newMin = minValueNode(root->p_right);
strcpy(root->value, newMin);
root->p_right= deleteNode(root->p_right, newMin);
}
}
return root;
}
//function to check if there is the exactchar char in the n position in the string
void charInExactPosition(struct BST *head, char exactchar, int n)
{
if( head != NULL ) {
charInExactPosition(head->p_left, exactchar, n);
if (head->value[n]!=exactchar){
deleteNode(head, head->value);}
charInExactPosition(head->p_right, exactchar, n);
}
}
void printTree(struct BST *root)
{
if( root != NULL ) {
printTree(root->p_left);
printf("%s\n", root->value);
printTree(root->p_right);
}
}
int main(){
struct BST* tree = NULL;
insertInTree("AAAAA", &tree, (Compare) CmpStr);
insertInTree("AkdAA", &tree, (Compare) CmpStr);
insertInTree("AAfAA", &tree, (Compare) CmpStr);
insertInTree("AdgAA", &tree, (Compare) CmpStr);
insertInTree("AhAAA", &tree, (Compare) CmpStr);
insertInTree("AAAiA", &tree, (Compare) CmpStr);
insertInTree("2AAAA", &tree, (Compare) CmpStr);
charInExactPosition(tree, 'A', 1);
printTree(tree);
}

How do I swap the nodes of a linked list in a bubble-sort algorithm?

In C I have to write a bubble sort function that swaps the nodes and not the values of a LinkedList, but I'm unable to accomplish it. Here is the code (As you can see the order is not correct):
#include <stdio.h>
#include <malloc.h> // malloc, free
#include <stddef.h> // NULL
// defining 'int' as data_t
typedef int data_t;
typedef struct node_s {
data_t data;
struct node_s* next;
} node_t;
node_t** list_new() {
node_t** list = malloc(sizeof **list);
if (!list) return NULL;
*list = NULL;
return list;
}
void list_delete(node_t** list) {
node_t *node, *next;
for (node = *list; node; node = next) {
next = node->next;
free(node);
}
}
node_t* list_push_front(node_t** list, data_t data) {
node_t* node = malloc(sizeof(node_t));
if (!node) return NULL;
node->data = data;
node->next = *list;
return *list = node;
}
// IS EASY TO SWAP THE VALUES
/*
void swap(data_t* a, data_t* b) {
data_t c = *a;
*a = *b;
*b = c;
}
void simple_bubble_sort(node_t** list) {
for(node_t* i = *list; i; i = i->next)
for(node_t* j = *list; j->next; j = j->next)
if(j->data > j->next->data)
swap(&(j->data), &(j->next->data));
}
*/
// MUCH LESS EASY TO SWAP THE NODES
void swap_node(node_t** prev_node_A, node_t** node_A, node_t** node_B) {
node_t *last_node = (*node_B)->next;
node_t *first_node = *node_A;
node_t *second_node = *node_B;
if (prev_node_A) {
(*prev_node_A)->next = second_node;
(*prev_node_A)->next->next = first_node;
(*prev_node_A)->next->next->next = last_node;
} else {
(*node_A) = second_node;
(*node_A)->next = first_node;
(*node_A)->next->next = last_node;
}
}
void simple_bubble_sort(node_t** list) {
for(node_t* i = *list; i->next; i = i->next)
for (node_t *j = *list; j->next->next; j = j->next) {
if (j == *list) {
if (j->data > j->next->data) {
*list = j->next;
swap_node(NULL, &j, &(j->next));
}
}
else {
if (j->next->data > j->next->next->data)
swap_node(&j, &(j->next), &(j->next->next));
}
//printf("%i,%i | %i, %i, %i, %i \n", i->data, j->data, (*list)->data, (*list)->next->data, (*list)->next->next->data, (*list)->next->next->next->data);
//system("pause");
}
}
int main() {
// Create List
node_t** list = list_new();
if (!list)
goto memory_allocation_failure;
// Add values to List
for(int i=0; i<10; i++)
if (!list_push_front(list, i))
goto memory_allocation_failure;
// Print List
for (node_t* node = *list; node != NULL; node = node->next)
printf("%i\n", node->data);
// Swap Test
//swap_node(NULL, &(*list), &((*list)->next));
//swap_node(&(*list), &((*list)->next), &((*list)->next->next));
// Sort List
printf("-- Bubble Sort --\n");
simple_bubble_sort(list);
// Print List
for (node_t* node = *list; node != NULL; node = node->next)
printf("%i\n", node->data);
// Delete List
list_delete(list);
return 0;
// Error Handler
memory_allocation_failure:
printf("Memory Allocation Failure");
return 1;
}
Here is the function swap.
void swap( node_t **current )
{
node_t *tmp = ( *current )->next->next;
( *current )->next->next = *current;
*current = ( *current )->next;
( *current )->next->next = tmp;
}
And here is the function simple_bubble_sort
void simple_bubble_sort( node_t **head )
{
if ( *head )
{
for ( node_t **first = head, *sorted = NULL, *last = sorted;
( *first )->next != last;
last = sorted )
{
sorted = ( *first )->next;
for ( node_t **current = first; ( *current )->next != last; current = &( *current )->next )
{
if ( ( *current )->next->data < ( *current )->data )
{
swap( current );
sorted = ( *current )->next;
}
}
}
}
}
Investigate them.
Pay attention to that the header <malloc.h> is not a standard C header. Instead use the header <stdlib.h>.
You need to revise your current code. For example this function
node_t** list_new() {
node_t** list = malloc(sizeof **list);
if (!list) return NULL;
*list = NULL;
return list;
}
does not make sense it should be removed.
What you need is just to define in main a pointer like
node_t *head = NULL;
And pass it to functions as for example to the function simple_bubble_sort like
simple_bubble_sort( &head );
Or the function list_push_front should be defined like
int list_push_front(node_t** list, data_t data)
{
node_t* node = malloc(sizeof(node_t));
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = *list;
*list = node;
}
return success;;
}

Doubly linked list - segfault

I have a doubly linked list,
struct node
{
int data;
struct node *prev;
struct node *next;
};
and a deleteEnd function I implemented,
bool deleteEnd(struct node **head, int* value) {
if (*head == NULL) return false;
struct node* end = *head;
while (end->next != NULL) {
end = end->next;
}
if (end == *head) *head = NULL;
else end->prev->next = NULL;
*value = end->data;
free(end);
return true;
}
that gives me a segmentation fault but I can't figure out why. At this point my list have 3 elements (1<->2<->5) and 5 should be deleted.
list.h
#pragma once
#include <stdbool.h>
/* doubly linked list structure */
struct node
{
int data;
struct node *prev;
struct node *next;
};
struct node* create(int value);
bool insertAtBeginning(struct node **head, int value);
bool insertAtEnd(struct node **head, int value);
bool insertAfter(struct node **head, int value, int preVal);
bool deleteBeginning(struct node **head, int* value);
bool deleteEnd(struct node **head, int* value);
bool deleteSpecific(struct node **head, int value);
void display(struct node *head);
list.c
#include "list.h"
#include <stdlib.h>
#include <stdio.h>
struct node* create(int value) {
struct node* n = malloc(sizeof(struct node));
if (n == NULL) return NULL;
n->data = value;
n->prev = NULL;
n->next = NULL;
return n;
}
bool insertAtBeginning(struct node **head, int value) {
struct node* old_head = *head;
*head = create(value);
if (*head == NULL) return false;
(*head)->next = old_head;
return true;
}
bool insertAtEnd(struct node **head, int value) {
// Get last node
struct node* last = *head;
while (last->next != NULL) {
last = last->next;
}
// Insert after
last->next = create(value);
if (last->next == NULL) return false;
else return true;
}
bool insertAfter(struct node **head, int value, int preVal) {
// Get previous
struct node* prev = *head;
while (prev->data != preVal && prev->next != NULL) {
prev = prev->next;
}
// Not founnd ?
if (prev->next == NULL && prev->data != preVal) return false;
// Insert in between
struct node* nxt = prev->next;
struct node* insert = create(value);
if (insert == NULL) return false;
prev->next = insert;
insert->next = nxt;
return true;
}
bool deleteBeginning(struct node **head, int* value) {
struct node* hd = *head;
*value = hd->data;
*head = (*head)->next;
free(hd);
return true;
}
bool deleteEnd(struct node **head, int* value) {
if (*head == NULL) return false;
struct node* end = *head;
while (end->next != NULL) {
end = end->next;
}
if (end == *head) *head = NULL;
else end->prev->next = NULL;
*value = end->data;
free(end);
return true;
}
bool deleteSpecific(struct node **head, int value) {
// Find node
struct node* n = *head;
while (n->data != value && n->next != NULL) {
n = n->next;
}
// Not found ?
if (n->next == NULL && n->data != value) return false;
// Deleting head ?
if (n == *head) {
*head = (*head)->next;
free(n);
}
// Delete in between
else {
struct node* nxt = n->next;
struct node* prev = n->prev;
prev->next = nxt;
free(n);
}
return true;
}
void display(struct node *head) {
if (head == NULL) {
printf("List is Empty!!!");
}
else {
printf("\nList elements are:\n");
do {
printf("%d ", head->data);
head = head->next;
}
while(head != NULL);
printf("\n\n");
}
}
main.c
#include <stdio.h>
#include "list.h"
int main()
{
int value, preVal, retVal;
struct node *head = NULL;
/* insert data */
value = 2;
printf("insert %d %s\n", value, insertAtBeginning(&head, value) ? "OK":"NOK");
display(head);
value = 5;
printf("insert %d %s\n", value, insertAtEnd(&head, value) ? "OK":"NOK");
display(head); // printf("blabla");
value = 3;
printf("insert %d %s\n", value, insertAtBeginning(&head, value) ? "OK":"NOK");
display(head);
value = 3;
preVal = 0;
printf("insert %d after %d %s\n", value, preVal, insertAfter(&head, value, preVal) ? "OK":"NOK");
display(head);
value = 1;
preVal = 3;
printf("insert %d after %d %s\n", value, preVal, insertAfter(&head, value, preVal) ? "OK":"NOK");
display(head);
/* delete data */
retVal = deleteBeginning(&head, &value);
printf("delete %d %s\n", value, retVal ? "OK": "NOK");
display(head);
retVal = deleteEnd(&head, &value);
printf("delete %d %s\n", value, retVal ? "OK": "NOK");
display(head);
value = 3;
retVal = deleteSpecific(&head, value);
printf("delete %d %s\n", value, retVal ? "OK":"NOK");
display(head);
return 0;
}
In case when end is equal to head this statement
end->prev->next = NULL; // <- segfault
results in undefined behavior because end->prev is equal to NULL;
I would define the function the following way
bool deleteEnd(struct node **head, int *value )
{
bool success = *head != NULL;
if ( success )
{
while ( ( *head )->next != NULL ) head = &( *head )->next;
*value = ( *head )->data;
struct node *last = *head;
*head = NULL;
free( last );
}
return success;
}
EDIT: After you showed additional code then it is already seen that at least this function
bool insertAtBeginning(struct node **head, int value) {
struct node* old_head = *head;
*head = create(value);
if (*head == NULL) return false;
(*head)->next = old_head;
return true;
}
is wrong because it does not set the data member prev of old_head.
Or in this function
bool insertAtEnd(struct node **head, int value) {
// Get last node
struct node* last = *head;
while (last->next != NULL) {
last = last->next;
}
// Insert after
last->next = create(value);
if (last->next == NULL) return false;
else return true;
}
there is no check whether *head is equal to NULL. And again the data member prev of the newly created node is not set appropriately.
This that is that the data member prev has the value NULL is the reason of incorrect work of the function deleteEnd.
You should revise all your functions.
You have to check if end element has previous one. If it does not have, you can't write next element to that previous element.
You are missing if statement.
if (end->prev)
end->prev->next = NULL; // <- segfault

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;
}

BST build tree double pointers

I am unsure how to set a pointer to a pointer to build a tree. Like once I have traveled to a leaf and call insert, how should I insert another element calling insert with the root node or the address of the root pointer? I think the problem with this function is the name root where that should be the double pointer right?
#include "bst.h"
#include <stdio.h>
#include <stdlib.h>
//arbitrary list of temp nodes
TreeNode *new_node, *root, *tmp, *parent;
int elemArray[100], i1, i2, i0;
int main( int argc, char *argv[] ) {
//Throw error is *Argv[] is not an integer
//assuming it was an integer
int cnt = atoi( argv[1] );
printf( "number is %d\n", cnt );
//
printf("Enter %i integer values to place in tree:\n", cnt);
for ( i1 = 0; i1 < cnt; ++i1) {
scanf( "%d", &elemArray[i1] );
}
//first ouput "INput Values"
printf( " Input Values:\n " );
for ( i2 = 0; i2 < cnt; ++i2) {
printf( "%d\n", elemArray[i2] );
}
TreeNode** root = (TreeNode*)malloc(sizeof(TreeNode*));
buildTree(root, elemArray, cnt );
printf( "Preorder:\n ");
//traverse
//TreeNode* tempN = malloc(sizeof(TreeNode*));
//tempN->data= 5;
traverse( root, PREORDER);
//traverse a single node
printf( "Inorder:\n ");
printf( "Postorder:\n ");
//Build tree with each element
return 0;
}
This is the .h file
/// The definition of the tree structure
typedef struct TreeNode {
int data ; // the data stored in the node
struct TreeNode* left ; // node's left child
struct TreeNode* right ; // node's right child
} TreeNode;
/// The three supported traversals
typedef enum {
PREORDER, // parent -> left -> right
INORDER, // left -> parent -> right
POSTORDER // left -> right -> parent
} TraversalType;
and lastly the traverse function so far as it failed the first test.
void traverse( const TreeNode* root, const TraversalType type ) {
if ( type == PREORDER) {
if (root != NULL)
{
printf("%d", root->data);
traverse( root->left, PREORDER);
traverse( root-> right, PREORDER);
}
}
}
void build_tree(TreeNode** root, const int elements[], const int count) {
TreeNode* node = malloc(sizeof(TreeNode*));
node->left = node ->right = NULL;
*root = node;
for ( int i0 = 0; i0 < count; ++i0 ){
TreeNode* node = malloc(sizeof(TreeNode*));
*root = node;
node->data = elements[cnt];
insertNode( &(*root), &node );
}
}
Why is the insertNode getting the errors (multiple) and I don't know which is the pointer and which is the struct. GUYS ANY HINT WILL BE HELPFUL PLEASE?
bst.c:94:20: error: request for member 'left' in something not a structure or union
insert(root->left, new_node);
void insertNode(TreeNode** root, TreeNode* new_node) {
if (new_node-> data < &root-> data) {
if (&root-> left == NULL)
&root-> left == new_node;
else
insert(root->left, new_node);
}
if (new_node->data > &root->data) {
if(&root-> right ==NULL)
&root->right = new_node;
else
insert(&root->right, new_node);
}
}
SO for Edit 2: I do have a header file which has a build_Tree(**root, elems[], sizeofElem[]), which means i need a helper function insert. Yes is would be easier to add by input starting*.
Edit 1
#include "bst.h"
#include <stdio.h>
#include <stdlib.h>
//arbitrary list of temp nodes
TreeNode *new_node, *root, *tmp, *parent, *current;
int elemArray[5], i1, i2, i0;
/*
Insert a new node into the tree by referencing the root and using recursion
*/
TreeNode* getN(int dataElem) {
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = dataElem;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
/** This func should just be the root of the tree in the parameter,
but I like the idea of a pointer becuase it helps to create a tempory
pointer rather than newNode
**/
TreeNode* addNodeToTree(TreeNode *root, int data) {
TreeNode *current = *root; //define the current pointer to the root always
TreeNode *parent = *root
TreeNode *newNode = getN(data);
if (*root == NULL)
{
printf("First Node");
*root = newNode;
}
else
{
while(current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
}
}
void build_Tree(TreeNode** root, const int elements[], const int count) {
*root = malloc(sizeof(TreeNode));
for ( i0 = 0; i0 < count; ++i0 ){
printf("%d\n", elements[count]);
addNodeToTree(&root, elements[count]);
}
}
int main( int argc, char *argv[] ) {
//Throw error is *Argv[] is not an integer
//assuming it was an integer
int cnt = atoi( argv[1] );
printf( "number is %d\n", cnt );
//
printf("Enter %i integer values to place in tree:\n", cnt);
for ( i1 = 0; i1 < cnt; ++i1) {
scanf( "%d", &elemArray[i1] );
}
//first ouput "INput Values"
printf( " Input Values:\n " );
for ( i2 = 0; i2 < cnt; ++i2) {
printf( "%d\n", elemArray[i2] );
printf("building tree0\n");
}
printf("building tree\n");
TreeNode** root = (TreeNode**)malloc(sizeof(TreeNode*));
TreeNode *root = NULL;
build_Tree(root, elemArray, cnt );
printf( "Preorder:\n ");
//traverse
//TreeNode* tempN = malloc(sizeof(TreeNode*));
//tempN->data= 5;
traverse( *root, PREORDER); //pass the pointer of root to traverse the tree
//traverse a single node
printf( "Inorder:\n ");
printf( "Postorder:\n ");
//Build tree with each element
return 0;
}
void traverse( const TreeNode* root, const TraversalType type ) {
if ( type == PREORDER) {
if (root != NULL)
{
printf("%d", root->data);
traverse( root->left, PREORDER);
traverse( root-> right, PREORDER);
}
}
}
/**
void insertNode(TreeNode** root, TreeNode* new_node) {
if (new_node-> data < *root-> data) {
if (*root-> left == NULL)
*root-> left == new_node;
else
insert(*root->left, new_node);
}
if (new_node->data > *root->data) {
if(*root-> right ==NULL)
*root->right = new_node;
else
insert(*root->right, new_node);
}
}
**/
//question1: what is the
Edit 2 for main and build_tree
void build_Tree(TreeNode** root, const int elements[], const int count) {
//*root = malloc(sizeof(TreeNode));
for ( i0 = 0; i0 < count; i0++ ){
//create the node
//
TreeNode *current = *root; //define the current pointer to the root always
TreeNode *parent = *root;
//dont create node
int data = elements[i0];
TreeNode *newNode = getN(data);
if (*root == NULL)
{
printf("First Node %d\n", elements[i0]);
*root = newNode;
}
else
{
printf("Next Node %d\n", elements[i0]);
while(current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
}
//return root;
}
}
TreeNode* getN(int dataElem) {
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = dataElem;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
int main( int argc, char *argv[] ) {
//Throw error is *Argv[] is not an integer
//assuming it was an integer
int cnt = atoi( argv[1] );
printf( "number is %d\n", cnt );
//
printf("Enter %i integer values to place in tree:\n", cnt);
for ( i1 = 0; i1 < cnt; ++i1) {
scanf( "%d", &elemArray[i1] );
}
//first ouput "INput Values"
printf( " Input Values:\n " );
for ( i2 = 0; i2 < cnt; ++i2) {
printf( "%d\n", elemArray[i2] );
printf("building tree0\n");
}
printf("building tree\n");
TreeNode* root; //= malloc(sizeof(TreeNode*));
root = NULL;
build_Tree(&root, elemArray, cnt );
printf( "Preorder:\n ");
//traverse
//TreeNode* tempN = malloc(sizeof(TreeNode*));
//tempN->data= 5;
//traverse( *root, PREORDER); //pass the pointer of root to traverse the tree
//traverse a single node
printf( "Inorder:\n ");
printf( "Postorder:\n ");
//Build tree with each element
return 0;
}
Say you created a function addNodeToTree(TreeNode *root, int data), pass the root node, and data to it as argument.
Now inside this function, simply create another variable say TreeNode *current = root which will help us basically to traverse the tree and place the node at its respective position, and TreeNode *newNode = NULL(this will become the new node, which is to be inserted).
Now before moving ahead, to actually place the node, we will first check, if the root is not null, i.e. the tree is EMPTY. For that, we will test:
if (root == NULL)
{
newNode = malloc(sizeof(*newNode)); // else we can make a function for this
// thingy too. Creating a function too,
// for you to look at.
root = newNode;
}
If the tree is not EMPTY, i.e. it contains a node already, then we will traverse the tree to find the place, where to put the new node. So the else part, will be like:
else
{
parent = current = root;
// This loop will actually help us, find the `parent`,
// of the `newNode`(which is to be inserted)
while (current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
// Now once, we have found, the node, under which the
// newNode will be placed, now we have to check, whether
// newNode will become a `left child/right child` of the
// parent.
newNode = getNewNode(data);
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
return root;
}
TreeNode * getNewNode(int data)
{
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
Now the newNode has been inserted, and you can simply traverse in any order to see the Tree.
EDIT 1:
Here is one working example, just see if this makes sense. Else please do ask any question, that might may arise.
#include <stdio.h>
#include <stdlib.h>
typedef struct TREENODE
{
int data;
struct TREENODE *left;
struct TREENODE *right;
}TreeNode;
void display(TreeNode *node)
{
printf("*********************************\n");
printf("Address of Node: %p\n", node);
printf("Data: %d\n", node->data);
printf("Left Child: %p\n", node->left);
printf("Right Child: %p\n", node->right);
printf("*********************************\n");
}
TreeNode * getNewNode(int data)
{
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
int getIntData(char *message)
{
int value = 0;
char buffer[BUFSIZ] = {'\0'};
fputs(message, stdout);
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &value);
return value;
}
TreeNode * addNodeToTree(TreeNode *root, int data)
{
TreeNode *current = root, *parent = root;
TreeNode *newNode = getNewNode(data);
if (root == NULL)
{
root = newNode;
}
else
{
while(current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
}
return root;
}
void inOrderTraversal(TreeNode *root)
{
if (root != NULL)
{
inOrderTraversal(root->left);
display(root);
inOrderTraversal(root->right);
}
}
int main(void)
{
TreeNode *root = NULL;
int data = 0;
data = getIntData("Enter Data: ");
root = addNodeToTree(root, data);
data = getIntData("Enter Data: ");
root = addNodeToTree(root, data);
data = getIntData("Enter Data: ");
root = addNodeToTree(root, data);
inOrderTraversal(root);
return EXIT_SUCCESS;
}
EDIT 2:
To make addNodeToTree(...), implement pointer to a pointer, one simply needs to change the function as:
void addNodeToTree(TreeNode **root, int data)
{
TreeNode *current = *root;
TreeNode *parent = *root;
TreeNode *newNode = getNewNode(data);
if (*root == NULL)
{
*root = newNode;
}
else
{
// same as before, just don't return anythingy, from the function.
// As the function uses pointer to a pointer, hence whatever changes
// are done, here will be reciprocated in the main function automatically
}
// no need to return anythingy
}
And the call from main will now look like:
int main(void)
{
TreeNode *root = NULL;
int data = 0;
data = getIntData("Enter Data: ");
addNodeToTree(&root, data);
// Just see the call to addNodeToTree(...), the rest is same, as before
}
EDIT 3:
In order to take elements from an array instead of adding them directly to tree, just change the main method to this form:
int main(void)
{
TreeNode *root = NULL;
int element[5] = {19, 11, 5, 28, 25};
int size = sizeof(element) / sizeof(element[0]);
int counter = 0;
for (counter = 0; counter < size; ++counter)
{
addNodeToTree(&root, element[counter]);
}
inOrderTraversal(root);
return EXIT_SUCCESS;
}

Resources