C doubly linked list - c

I am trying to implement (BST) with doubly linked list in C with loops. but something I couldn't understand why one could is work as expected and the other is not.
look at first code which is working well.
#include<stdio.h>
#include<stdlib.h>
typedef struct Node {
int data;
struct Node* left;
struct Node* right;
} Node;
typedef struct BST {
Node* root;
}BST;
Node * createNode(int value) {
Node * a= (Node* )malloc(sizeof(Node));
a->left = NULL;
a->right = NULL;
a->data = value;
return a;
}
void printBST(Node * bst) {
if(bst == NULL) {return; }
printf("%d ", bst->data);
printBST(bst->left);
printBST(bst->right);
}
Node* createRandomBST(size_t len){
if(len == 0) {return NULL;}
Node* tempBST = createNode(rand()%200);
printf(" root: %d \n", tempBST->data);
Node* ptr_1;
Node *ptr_2;
ptr_1 = tempBST;
ptr_2 = tempBST;
for(int i = 0; i < len; i++) {
int value = i*i+22;
tempBST = ptr_1;
while (1)
{
if(value >= tempBST->data) {
if(tempBST->right == NULL) {
tempBST->right = createNode(value);
printf("right-I: %d, value:%d \n", i, tempBST->data);
break;
}
tempBST = tempBST ->right;
}else {
if(tempBST->left == NULL) {
tempBST->left = createNode(value);
printf("left-I: %d, value:%d \n", i, value);
break;
}
tempBST= tempBST->left;
}
}
}
return ptr_2;
}
Second code which isn't working as expected.
#include<stdio.h>
#include<stdlib.h>
typedef struct Node {
int data;
struct Node* left;
struct Node* right;
} Node;
typedef struct BST {
Node* root;
}BST;
Node * createNode(int value) {
Node * a= (Node* )malloc(sizeof(Node));
a->left = NULL;
a->right = NULL;
a->data = value;
return a;
}
void printBST(Node * bst) {
if(bst == NULL) {return; }
printf("%d ", bst->data);
printBST(bst->left);
printBST(bst->right);
}
Node* createRandomBST(size_t len){
if(len == 0) {return NULL;}
Node* tempBST = createNode(rand()%200); //start by creating root node.
printf(" root: %d \n", tempBST->data); // print the root node
Node* ptr_1;
Node *ptr_2;
ptr_1 = tempBST; // ptr_1 and ptr_2 are copy of the root node.
ptr_2 = tempBST;
for(int i = 0; i < len; i++) { // start the loop -- tempBST , ptr_1 and ptr_2 are all pointing to the root node
int value = i*i+22; //the value needed to be inserted.
tempBST = ptr_1; // every time need to insert a node it will start from the root node.
while (1) //loop until insertion is happend
{
if(value >= tempBST->data) { //if the value greater than the root->data then go right
tempBST = tempBST ->right; // now tempBST is pointing to tempBST->right not the root
if(tempBST == NULL) { //if tempBST is null then the insertion will happened else loop with tempBST-> as the root..
tempBST = createNode(value); //if tempBST->right is empty insert the node.
printf("right-I: %d, value:%d \n", i, tempBST->data);
break; break;
}
}else { //if the value greater than the root->data then go left
tempBST = tempBST ->left; // now tempBST is pointing to tempBST->left not the root
if(tempBST == NULL) {
tempBST = createNode(value); //if tempBST->left is null then the insertion will happened else loop with tempBST-> as the root..
printf("left-I: %d, value:%d \n", i, value);
break;
}
}
}
}
return ptr_2; //return a pointer the root;
}
int main() {
Node* tem;
tem = createRandomBST(20);
printf("%d ", tem->data);
printBST(tem);
}
I tried to debug it with GDB I couldn't understand the problem.
in the first code the printBST() print all the nodes but in the second one only the root is being printed

Related

delete the biggest number in linked list from anywhere (in C)

I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
int x;
struct Node *next;
} Node;
void deallocate(Node **root)
{
Node *curr = *root;
while (curr != NULL)
{
Node *aux = curr;
curr = curr->next;
free(aux);
}
*root = NULL;
}
void insert_end(Node **root, int value)
{
Node *new_node = malloc(sizeof(Node));
if (new_node == NULL)
{
exit(1);
}
new_node->next = NULL;
new_node->x = value;
if (*root == NULL)
{
*root = new_node;
return;
}
Node *curr = *root;
while (curr->next != NULL)
{
curr = curr->next;
}
curr->next = new_node;
}
void deserialize(Node **root)
{
FILE *file = fopen("duom.txt", "r");
if (file == NULL)
{
exit(2);
}
int val;
while (fscanf(file, "%d, ", &val) > 0)
{
insert_end(root, val);
}
fclose(file);
}
int largestElement(struct Node *root)
{
int max = INT_MIN;
while (root != NULL)
{
if (max < root->x)
max = root->x;
root = root->next;
}
return max;
}
void deleteN(Node **head, int position)
{
Node *temp;
Node *prev;
temp = *head;
prev = *head;
for (int i = 0; i < position; i++)
{
if (i == 0 && position == 1)
{
*head = (*head)->next;
free(temp);
}
else
{
if (i == position - 1 && temp)
{
prev->next = temp->next;
free(temp);
}
else
{
prev = temp;
// Position was greater than
// number of nodes in the list
if (prev == NULL)
break;
temp = temp->next;
}
}
}
}
int main()
{
Node *root = NULL;
printf("MENU:\n");
printf("if you press 0 the list will be created \n");
printf("if you press 1 the list will be printed on a screen\n");
printf("if you press 2 it deletes the biggest element\n");
printf("if you press 3 the program ends\n\n");
int meniu;
printf("press:\n");
scanf("%d", &meniu);
while (meniu != 3)
{
if (meniu == 0)
{
deserialize(&root);
printf("sarasas sukurtas.\n");
}
if (meniu == 1)
{
for (Node *curr = root; curr != NULL; curr = curr->next)
printf("%d\n", curr->x);
}
if (meniu == 2)
{
int max_element = largestElement(root);
printf("%d max\n", max_element);
deleteN(&root, max_element);
}
printf("press:\n");
scanf("%d", &meniu);
}
deallocate(&root);
return 0;
}
When I compile and run the delete function it only deletes the biggest number first time and if I call it second time it deletes the last number of the list. Can someone help me fix that?
I edited it so all of the code can be seen because it was hard to understand it like I had it before
Your largestElement returns the largest data value in the list.
However, here:
int max_element = largestElement(root);
printf("%d max\n",max_element);
deleteN(&root, max_element);
you use the return value as if it is the position of the node with the largest element.
Instead of largestElement you need a function that returns the position of the element with the largest data value.
It would look something like:
int positionOfLargestElement(struct Node* root)
{
int pos = 0;
int maxpos = 0;
int max = INT_MIN;
while (root != NULL) {
++pos;
if (max < root->x)
{
max = root->x;
maxpos = pos;
}
root = root->next;
}
return maxpos;
}
note: The exact code depends a bit on whether the first node is considered to be position 0 or position 1 but the principle is the same.

Pointer set to NULL but not in debugger

So I am working o AVL tree, however I cant seem to either get the delete function working nor freeing the tree right. The delete function segfaults everytime, but the free function segfaults when in the debugger.
Here is gdb's stack trace:
#0 0x00007fffd935a87a in msvcrt!_memicmp_l () from C:\WINDOWS\System32\msvcrt.dll
#1 0x0000000000402811 in isPresentRecurs (root=0xb756d0, searchedValue=0xb795b0 "aaa", found=0x61fcec) at ../.source/binTree.c:206
#2 0x00000000004027d6 in isPresent (root=0xb756d0, searchKey=0xb795b0 "aaa") at ../.source/binTree.c:200
#3 0x0000000000401c3d in main () at test.c:110
In my tests I check if the root has been set to NULL, which running it normally does finish however running it inside the debugger does not and instead goes into the else statement:
Minimal Example (test.c):
#include "binTree.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define TRACE 0
#define MAX_SEARCH_ITEMS 20
void fillTree(binTree **tree);
void fillSearchValues( char **valArray);
void fillTree(binTree** tree){
printf( "Constructing tree\n\n" );
char key[200] ="";
for(int j=1 ;j<4;j++ ){
memset(&key,0,199);
for(int i=0; i<26; i++){
for(int k = 0;k<j;k++) key[k]= i+'a';
Var value;
value.data = malloc(sizeof(varData));
value.data->iData = j;
value.type =INTEGER;
(*tree)->root= insert((*tree)->root,key,value);
if(TRACE) printf("key: %s, value: %d\n",(*tree)->root->key,(*tree)->root->value.data->iData);
}
}
(*tree)->nodeCount = getSizeBinaryTree((*tree)->root);
printf( "\n\nTree constructed\n\n" );
}
void fillSearchValues( char **valArray){
char key[200]="";
for(int j=1 ;j<4;j++ ){
memset(&key,0,199);
for(int i=0; i<26; i++){
if(i*j>MAX_SEARCH_ITEMS) break;
for(int k = 0;k<j;k++) key[k]= i+'a';
*(valArray+i*j) = strdup(key);
if (TRACE)printf ("%s read; %s inserted\n", key, valArray[i*j] );
}
}
}
int main(){
binTree *tree = createNewTree();
fillTree(&tree);
printTree(tree->root);
/* //Fails at delete
for(int i=0;i<26;i++){
char string = i+'a';
tree->root = Delete(tree->root,&string);
}*/
printf("\nFreeing Tree: \n=================================\n");
freeTree(tree->root);
if(tree->root==NULL) printf("Tree has been freed successfully\n");
else printf("Failed to free tree \n");
// searching after freeing
int found =0; int lost =0;
char *values[MAX_SEARCH_ITEMS];
fillSearchValues(values);
for(int i=0;i<MAX_SEARCH_ITEMS;i++){
if(isPresent(tree->root,values[i])){
if (TRACE)printf("found search value %s\n",values[i]);
found++;
}else{
lost++;
if(TRACE)printf("didnot find search value %s\n",values[i]);
}
}
printf("found %d of %d while cleared %d\n", found,MAX_SEARCH_ITEMS,lost);
free(tree);
return 0;
}
binTree.h:
#ifndef BINTREE_H
#define BINTREE_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define COUNT 10
typedef enum TYPE {INTEGER, FLOAT, CHARACTER} TYPE;
typedef union {
float fData;
int iData;
char cData;
} varData;
typedef struct Var{
varData * data;
TYPE type;
} Var;
typedef struct Node{
char* key;
Var value;
int height;
struct Node *left;
struct Node *right;
}Node;
typedef struct binTree{
Node *root;
unsigned int nodeCount;
}binTree;
int max(int a,int b);
binTree *createNewTree();
Node *newNode(char *key,Var value);
void freeTree(Node *node);
void freeNode(Node *node);
Node *insert(Node *node,char *key,Var value);
Node *rightRotate(Node *n);
Node *leftRotate(Node *n);
int height(Node *node);
int getBalance(Node *N);
void printTree(Node *root);
void printTreeS(Node *root,int space);
int isPresent(Node *root,char *searchKey);
void isPresentRecurs(Node *root,char *searchedValue,int *found);
Node *minValueNode(Node *node);
Node *search(Node *node,char *key);
Node *Delete(Node *root,char *key);
int getSizeBinaryTree(Node* root);
#endif
binTree.c
#include "binTree.h"
int max(int a, int b){
return (a > b)? a : b;
}
binTree* createNewTree(){
binTree *t = (binTree *) malloc(sizeof(binTree));
if(!t){
printf("Failed at allocationg tree\n");
exit(-1);
}
t->root = NULL;
return t;
}
Node* newNode(char * key,Var value){
Node *p = (Node*)malloc(sizeof(Node));
if(!p){
printf("Failed at allocationg node\n");
exit(-1);
}
p->key = strdup(key);
p->value = value;
p->left=p->right=NULL;
p->height = 1;
return p;
}
void freeTree(Node* node){
if (node==NULL) return;
freeTree(node->left);
freeTree(node->right);
freeNode(node);
node=NULL;
}
void freeNode(Node *node){
free(node->value.data);
node->value.data = NULL;
free(node->key);
node->key = NULL;
free(node);
node = NULL;
}
Node* insert(Node *node, char *key,Var value){
if (node == NULL) return newNode(key,value);
if ( strcasecmp(key ,node->key)<0) node->left = insert(node->left, key,value);
else if (strcasecmp(key ,node->key)>0) node->right = insert(node->right, key,value);
else if(strcasecmp(key,node->key)==0){
if(memcmp(&value.data,&node->value,sizeof(Var))!=0){
memcpy(&node->value,&value,sizeof(Var));
}
return node;
};
node->height = max(height(node->left),height(node->right))+1;
int balance = getBalance(node);
// Left Left Case
if (balance > 1 && strcasecmp(key, node->left->key)<0)
return rightRotate(node);
// Right Right Case
if (balance < -1 && strcasecmp(key, node->right->key)>0)
return leftRotate(node);
// Left Right Case
if (balance > 1 && strcasecmp(key, node->left->key)>0){
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && strcasecmp(key,node->right->key)<0){
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
Node *rightRotate(Node *n){
Node *leftNode =n->left;
if(!leftNode) return n;
Node *rightOfLeft =leftNode->right;
leftNode->right = n;
n->left = rightOfLeft;
n->height = max(height(n->left), height(n->right)) + 1;
leftNode->height = max(height(leftNode->left), height(leftNode->right)) + 1;
return leftNode;
}
Node *leftRotate(Node *n){
Node *rightNode = n->right;
if(!rightNode) return n;
Node *leftOfright = rightNode->left;
rightNode->left = n;
n->right = leftOfright;
n->height = max(height(n->left), height(n->right)) + 1;
rightNode->height = max(height(rightNode->left), height(rightNode->right)) + 1;
return rightNode;
}
int height(Node *node){
if (!node) return 0;
return node->height;
}
int getBalance(Node *N){
if (N == NULL) return 0;
return height(N->left) - height(N->right);
}
void printTree(Node *root){
printTreeS(root, 0);
}
void printTreeS( Node *root, int space){
if (root == NULL)
return;
space += COUNT;
printTreeS(root->right, space);
printf("\n");
for (int i = COUNT; i < space; i++) printf(" ");
if (root->value.type == CHARACTER)printf("type: CHAR key: %s value: %s\n", root->key, root->value.data->cData);
if (root->value.type == INTEGER)printf("type: INT key: %s value: %d\n", root->key, root->value.data->iData);
if (root->value.type == FLOAT)printf("type: FLOAT key: %s value: %f\n", root->key, root->value.data->fData);
printTreeS(root->left, space);
}
int isPresent(Node* root, char* searchKey){
int found = 0;
isPresentRecurs( root, searchKey, &found );
return found;
}
void isPresentRecurs( Node *root,char *searchedValue,int* found ){
if (root) {
if (strcasecmp(root->key,searchedValue)==0)
*found = 1;
else {
isPresentRecurs(root->left, searchedValue, found);
if (!(*found))
isPresentRecurs( root->right, searchedValue, found);
}
}
}
Node * minValueNode(Node* node){
if(!node) return NULL;
if(node->left )return minValueNode(node->left);
return node;
}
Node *search(Node *node, char *key){
if (node == NULL || strcmp(node->key, key)==0)return node;
if (strcmp(node->key, key)<0) return search(node->right, key);
return search(node->left, key);
}
int getSizeBinaryTree(Node* root){
if (root) return 1 +getSizeBinaryTree( root->left ) + getSizeBinaryTree( root->right );
else return 0;
}
Node* Delete(Node* root,char *key) {
if (root==NULL) return root;
else if (strcasecmp(key ,root->key)>0) root->left =Delete(root->left,key);
else if (strcasecmp(key ,root->key)<0) root->right = Delete(root->right,key);
else {
if(root->right==NULL && root->left==NULL) {
free(root);
root = NULL;
}
else if(root->left!=NULL && root->right==NULL) {
Node* temp = root->left;
root = root->left;
freeNode(temp);
}
else if(root->right!=NULL && root->left==NULL) {
Node* temp = root->right;
root = root->right;
freeNode(temp);
}
else {
Node* temp = minValueNode(root->right);
root->key= temp->key;
root->value = temp->value;
root->right = Delete(root->right,temp->key);
}
}
if(root==NULL) return root;
root->height = 1 + max(height(root->left),height(root->right));
int balance = getBalance(root);
//Left Left Case
if(balance > 1 && getBalance(root->left) >=0) return rightRotate(root);
// Right Right Case
if(balance < -1 && getBalance(root->right) <=0) return leftRotate(root);
// Left Right Case
if(balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
//Right Left Case
if(balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
This is a mistake:
freeTree(tree->root);
if(tree->root==NULL) printf("Tree has been freed successfully\n");
else printf("Failed to free tree \n");
C uses pass-by-value, so it is not possible for freeTree to set tree->root to NULL.
The line node = NULL; inside the freeTree function sets the function parameter (which is a copy of the argument), it does not modify the argument in the calling context.
The function does free the pointed-to memory, which renders all pointers to that memory indeterminate, so the test tree->root == NULL actually causes undefined behaviour by using an indeterminate value.
Your compiler should warn about a dead-store for node=NULL; , if you do not see a warning then try turning up the warning and/or optimization level in your compiler, or running a static analyzer such as clang-tidy. freeNode has a similar issue.
To fix the problem, either change the calling code, e.g. freeTree(tree->root); tree->root = NULL;, or you will have to use pass-by-pointer, i.e. pass the address of the node you want to free.

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.

How I can balanced a tree into array

I have made a working binary tree.
Now I want when I press option # 4, it'll show binary tree is sorted according to the array (that means the middle should be root, the left part of the left subtree, then the right part of the field to the right subtree).
I have created functions required to do what it should be done but still it does not work as it should.
I have created NodSize(), it controls how many nodes are in the tree.
I have created balanceTree(), it takes all that is in the root.
I have created ArrayInorder(),
And Balance(), it makes balancing the tree according to array.
Where did I do wrong and how can I solve it?
..
You can see down here how I made it:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define MAX 100
struct tree
{
int data;
struct tree *left;
struct tree *right;
};
struct tree *CreateNode(int data)
{
struct tree *node = (struct tree*) malloc(sizeof(struct tree));
if (node != NULL)
{
node->data = data;
node->left = NULL;
node->right = NULL;
}
return node;
}
struct tree *insert(struct tree *root, int data)
{
if (root == NULL)
{
root = CreateNode(data);
}
if (root->data > data)
{
if (root->left == NULL)
{
root->left = CreateNode(data);
}
else
{
insert(root->left, data);
}
}
else if (root->data < data)
{
if (root->right == NULL)
{
root->right = CreateNode(data);
}
else
{
insert(root->right, data);
}
}
return root;
}
struct tree *delet(struct tree *ptr, int x)
{
struct tree *p1, *p2;
if (!ptr)
{
printf("\n NOTHING ");
return(ptr);
}
else
{
if (ptr->data < x)
{
ptr->right = delet(ptr->right, x);
}
else if (ptr->data > x)
{
ptr->left = delet(ptr->left, x);
return ptr;
}
else
{
if (ptr->data == x)
{
if (ptr->left == ptr->right)
{
free(ptr);
return(NULL);
}
else if (ptr->left == NULL)
{
p1 = ptr->right;
free(ptr);
return p1;
}
else if (ptr->right == NULL)
{
p1 = ptr->left;
free(ptr);
return p1;
}
else
{
p1 = ptr->right;
p2 = ptr->right;
while (p1->left != NULL)
p1 = p1->left;
p1->left = ptr->left;
free(ptr);
return p2;
}
}
}
}
return(ptr);
}
void Findroot(struct tree *root)
{
if (root != NULL)
{
printf("\nRoot is %d\n", root->data);
}
else
{
printf("\nNOTHING\n");
}
}
void inorder(struct tree *root)
{
if (root != NULL)
{
inorder(root->left);
printf(" %d", root->data);
inorder(root->right);
}
return;
}
int NodSize(struct tree *root)
{
if (root == NULL)
return 0;
else
return (NodSize(root->left) + 1 + NodSize(root->right));
}
void DestoryTree(struct tree * root)
{
if (root == NULL)
return;
DestoryTree(root->left);
DestoryTree(root->right);
printf("\n Destory node: %d", root->data);
free(root);
}
struct tree *Balance(int arr[], int start, int end)
{
if (start > end)
return NULL;
int mid = (start + end) / 2;
struct tree *root = CreateNode(arr[mid]);
root->left = Balance(arr, start, mid - 1);
root->right = Balance(arr, mid + 1, end);
return root;
}
int ArrayInorder(struct tree *root, int *arr, int helper)
{
if (root != NULL)
{
helper = ArrayInorder(root->left, arr, helper);
arr[helper] = root->data;
helper++;
helper = ArrayInorder(root->right, arr, helper);
}
return helper;
}
void balanceTree(struct tree *root)
{
int *arr, size;
size = NodSize(root);
arr = (int*)malloc(sizeof(int)*size);
ArrayInorder(root, arr, 0);
//DestoryTree(root);
root = Balance(arr, 0, size - 1);
}
void CreateBalancedTreeFromArray(struct tree *root, int *arr, int size)
{
DestoryTree(root);
root = Balance(arr, 0, size - 1);
}
int main(void)
{
struct tree *root;
int valja, item, dele;
root = NULL;
do
{
do
{
printf("\n1. Add a node to BINARY TREE ");
printf("\n2. Delete a node from BINARY TREE ");
printf("\n3. Show ROOT");
printf("\n4. Show Balanced Tree IN (Array)");
printf("\n5. Stang");
printf("\nYour choice? : ");
scanf(" %d", &valja);
if (valja<1 || valja>5)
printf("\n Fel - Try again");
} while (valja<1 || valja>5);
switch (valja)
{
case 1:
system("cls");
printf("\n Write a new element: ");
scanf("%d", &item);
root = insert(root, item);
printf("\n root is %d \n", root->data);
printf("INORDER: ");
inorder(root);
printf("\n");
break;
case 2:
system("cls");
printf("\n Write an element to delete: ");
scanf(" %d", &dele);
root = delet(root, dele);
printf("\n");
break;
case 3:
system("cls");
Findroot(root);
printf("\n");
break;
case 4:
balanceTree(root);
Findroot(root);
inorder(root);
break;
default:
printf("\n bye ");
}
} while (valja != 5);
return(0);
}
The problem is here:
void balanceTree(struct tree *root)
Although this function works, the new root that is created is NOT returned to the caller because root has been passed by value. You need to change the function to:
struct tree *balanceTree(struct tree *root)
and add this at the end:
return root;
Call the function with:
root = balanceTree(root);

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