Programming binary tree preOrder function - c

I'm trying to write a recursive function to print out the values in preorder. However, for some reason, it keeps printing out the same as my inOrder function. The postOrder function works fine, but I had to do the recursive function slightly differently for that one. Can you guys take a look at my code below and let me know what's wrong? I really appreciate it cuz this has been giving me trouble ALL day. Thanks in advance
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#define TRUE 1
#define FALSE 0
typedef struct bnodestruct
{
int value;
struct bnodestruct *left;
struct bnodestruct *right;
}bnode;
typedef bnode *bnodePtr;
void displayMenu();
void insert (bnodePtr *hd, int val);
void inOrder(bnodePtr hd);
void preOrder(bnodePtr hd);
void postOrder(bnodePtr hd);
void empty (bnodePtr *hd);
int main (int argc, char **argv)
{
int val;
bnodePtr head;
head = NULL;
char option;
int result = 0;
while(1)
{
displayMenu();
printf("Choose an option : ");
scanf("\n%c", &option);
/*printf("The option chosen is %c\n", option);*/
switch (option)
{
case 'q':
printf("The program is exiting...\n");
exit(-1);
case 'i':
printf("Enter an integer value to be inserted into the linked list : ");
scanf("%d", &val);
insert(&head, val);
break;
case 'o':
inOrder(head);
break;
case 'n':
preOrder(head);
break;
case 'p':
postOrder(head);
break;
case 'e':
empty(&head);
/*inOrder (head);*/
break;
}
}
}
void displayMenu()
{
printf("\n Menu \n");
printf("(q): quit the program\n");
printf("(i): insert integer value into the binary tree\n");
printf("(e): empty all values from the binary tree\n");
printf("(o): list the items contained in the binary tree in order\n");
printf("(n): list the items contained in the binary tree in pre order\n");
printf("(p): list the items contained in the binary tree in post order\n");
}
void insert (bnodePtr *hd, int val)
{
if (*hd == NULL)
{
*hd = (bnodePtr)malloc(sizeof(bnode));
(*hd)->left = NULL;
(*hd)->value = val;
(*hd)->right = NULL;
}
else
{
if (val < ((*hd)->value))
insert (&((*hd)->left), val);
else if (val > ((*hd)->value))
insert (&((*hd)->right), val);
}
}
void empty (bnodePtr *hd)
{
bnodePtr temp1 = *hd;
bnodePtr temp2;
while (temp1 != NULL)
{
temp2 = temp1;
temp1 = temp1->left;
free (temp2);
}
*hd = NULL;
}
void inOrder (bnodePtr hd)
{
if (hd != NULL)
{
inOrder(hd->left);
printf("%d\n", hd->value);
inOrder(hd->right);
}
}
void preOrder (bnodePtr hd)
{
if (hd != NULL)
{
printf("%d\n", hd->value);
preOrder(hd->left);
preOrder(hd->right);
}
}
void postOrder (bnodePtr hd)
{
if (hd != NULL)
{
inOrder(hd->left);
inOrder(hd->right);
printf("%d\n", hd->value);
}
}

void postOrder (bnodePtr hd)
{
if (hd != NULL)
{
inOrder(hd->left); // XXX
inOrder(hd->right); // XXX
printf("%d\n", hd->value);
}
}
That's your problem right there. You're calling inOrder where you should be calling postOrder.

Related

Double Linked List query

so i have created a program which uses double linked list and
performs some operations on it . The problem is that it displays garbage
values
at the end every time i try to create a linked list and then display it.
whats wrong in my code?(sorry! for the bad indentations)
if the linked list i created has elements say 15 and 16, it displays it as
15 16 25710 0 0
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct dll
{
int data;
struct dll *llink;
struct dll *rlink;
};
typedef struct dll *node;
node head=NULL;
void create();
int search(int u);
void insert(int num1);
void Delete(int num2);
void display();
node getnode();
int main()
{
int i,num,o;
while(1)
{
printf("\n1.create a list\n 2. insert before a search node\n 3. delete a node\n 4.display\n 5.exit\n");
scanf("%d",&num);
switch(num)
{
case 1 :
create();
break;
case 2 :
printf("enter the value before which you want to enter the node\n");
scanf("%d",&i);
insert(i);
break;
case 3 :
printf("enter the value to be deleted\n");
scanf("%d",&o);
Delete(o);
break;
case 4 :
printf("the linked list has :\n");
display();
break;
case 5 :
getch();
exit(1);
default :
printf("enter the correct option\n");
break;
}
}
}
node getnode()
{
node temp1;
temp1=(node)malloc(sizeof(node));
temp1->llink=NULL;
temp1->rlink=NULL;
return temp1;
}
void create()
{
node nn;
int num,y;
if(head==NULL)
head=getnode();
while(1)
{
printf("enter the data for the node");
scanf("%d",&num);
head->data=num;
printf("do you want to create another node(1/0):\n");
scanf("%d",&y);
if(y==1)
{
nn=getnode();
nn->rlink=head;
head->llink=nn;
head=nn;
nn=NULL;
}
else
break;
}
}
void insert (int num1)
{
int i,n,k;
node temp=head,nn;
n=search(num1);
if(n==0)
{
printf("element not present in the linked list");
}
if(n==1)
{
nn=getnode();
printf("enter the data for the node");
scanf("%d",&k);
nn->data=k;
nn->rlink=head;
head->llink=nn;
head=nn;
nn=NULL;
}
else
{
for(i=2; i<=n; i++)
temp=temp->rlink;
nn=getnode();
temp->llink->rlink=nn;
nn->llink=temp->llink;
nn->rlink=temp;
temp->llink=nn;
}
}
void Delete(int num2)
{
node temp=head;
int p,i;
p=search(num2);
if(p==0)
{
printf("no element is found");
}
if(p==1)
{
printf("the deleted element is %d",head->data);
head=head->rlink;
head->llink=NULL;
free(temp);
}
else
{
for(i=2; i<=p; i++)
{
temp=temp->rlink;
}
temp->llink->rlink=temp->rlink;
temp->rlink->llink=temp->llink;
free(temp);
temp=temp->rlink;
}
}
int search(int u)
{
node temp=head;
int pos=0;
if(u==head->data)
return 1;
else
{
while(temp!=NULL)
{
pos++;
if(temp->data==u)
{
printf("element found\n");
return(pos);
}
temp=temp->rlink;
}
}
if(temp==NULL)
{
return 0;
}
return -1;
}
void display()
{
node temp=head;
while(temp!=NULL)
{
printf("%d\n",temp->data);
temp=temp->rlink;
}
}
This:
temp1=(node)malloc(sizeof(node));
is a major error. Since you're "hiding a star", and node is a typedef for a pointer type, you're not allocating enough memory. It should be:
node temp1 = malloc(sizeof *temp1);
But I really recommend against typedefing a pointer away, it just makes things confusing.

Link List Add elements in recursion language C

#include <stdio.h>
#include <stdlib.h>
typedef struct nodeNum
{
int num;
struct nodeNum *next;
} t_nodeNum;
// Functions declaration ----------------------------
int menu(); // display menu and return choice
t_nodeNum* addition(t_nodeNum *node, int n);
void print_list(t_nodeNum *node);
// ----------------------------------------------------
// Main program to test link list functions
int main()
{
int choice;
t_nodeNum *pnode = NULL;
t_nodeNum *head = NULL;
t_nodeNum *temp = NULL;
int numAdd = 0;
int len = 0;
int first = 1;
do
{
choice = menu();
switch (choice)
{
case 1:
{
printf("Please enter number : \n");
scanf("%d", &numAdd);
if (first)
{
pnode = (t_nodeNum *)malloc(sizeof(t_nodeNum));
if (pnode == NULL)
{
printf("\n Error in allocation\n");
exit(0);
}
pnode->num = numAdd;
pnode->next = NULL;
first = 0;
head = pnode;
}
pnode = addition(pnode, numAdd);
break;
}
case 4:
{
printf("\n Print List: ");
print_list(head);
break;
}
}
}
while (choice != 5);
return 0;
}
// function menu display menu and return choice
int menu()
{
int choice = 0;
do
{
printf("Please choose option to do: \n");
printf("1. addition\n");
printf("2. deletion\n");
printf("3. search\n");
printf("4. print\n");
printf("5. exit\n");
printf("\n option = ");
scanf("%d", &choice);
}
while (choice < 1 || choice > 5);
return choice;
}
// function addition to add item to linked list in recursion
t_nodeNum* addition(t_nodeNum *p, int numAdd)
{
int len = 0;
if (p == NULL)
{
p = (t_nodeNum *)malloc(sizeof(t_nodeNum));
if (p == NULL)
{
printf("\n Error in allocation\n");
exit(0);
}
p->num = numAdd;
p->next = NULL;
}
else
{
p = addition(p->next, numAdd);
}
return (p);
}
// function print_list to print linked list in recursion
void print_list(t_nodeNum *head)
{
printf("%d ", head->num);
if (head->next == NULL)
{
printf("\n");
return;
}
print_list(head->next);
}
There is problem with the addition function it does not work correctly to add new item to the linked list and I does not know what is wrong please help
After adding new items and do print list it display only the first item
In you main function -
pnode = addition(pnode, numAdd);
instead of pnode you need to pass pnode->next -
pnode = addition(pnode->next, numAdd);
Problem with first call is that pnode is not NULL so it just adds new element at head position replacing previous value and returns.
Therefore, new node is not being created.

C fifo linked list char push

I'm currently trying to understand fifo linked list and found example here Example , and I'm trying to input char instead of int
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct Node
{
char Data;
struct Node* next;
}*rear, *front;
void delQueue()
{
struct Node *temp, *var=rear;
if(var==rear)
{
rear = rear->next;
free(var);
}
else
printf("\nQueue Empty");
}
void push(char *value)
{
struct Node *temp;
temp=(struct Node *)malloc(sizeof(struct Node));
temp->Data=value;
if (front == NULL)
{
front=temp;
front->next=NULL;
rear=front;
}
else
{
front->next=temp;
front=temp;
front->next=NULL;
}
}
void display()
{
struct Node *var=rear;
if(var!=NULL)
{
printf("\nElements are as: ");
while(var!=NULL)
{
printf("\t%d",var->Data);
var=var->next;
}
printf("\n");
}
else
printf("\nQueue is Empty");
}
int main()
{
int i=0;
char ch;
front=NULL;
printf(" \n1. Push to Queue");
printf(" \n2. Pop from Queue");
printf(" \n3. Display Data of Queue");
printf(" \n4. Exit\n");
while(1)
{
printf(" \nChoose Option: ");
//scanf("%d",&i);
ch = getchar();
switch(ch)
{
case '+':
{
char value[20];
printf("\nEnter a valueber to push into Queue : ");
scanf("%s", value);
push(value);
printf("%s",value);
display();
break;
}
case '-':
{
delQueue();
display();
break;
}
case '*':
{
display();
break;
}
case '$':
{
exit(0);
}
default:
{
printf("\nwrong choice for operation");
}
}
}
}
I can't understand this warning on line 26: warning: assignment makes integer from pointer without a cast
I can input text, for example: "Hello world", but when I want to display it, it is showed as "-9".
I am really confused.
Data is defined as char, but your assigning a char * (char pointer) to it. That creates the warning, and surely won't work as you expect.
In your Node struct, the value is of type char, but you're assigning a char* to it instead. This is why you get the warning, and why printing things doesn't come out right.

Passing pointers between functions in an implementation of linked list

The problem was solved. A guy gave it in comments. The problem was that I was using %d to read in a short int. I should have used %hd or I should have used an `int'.
I tried to create a program of singly-linked list using only local variables. I was able to make a working program by using global variables.
The program with local variables compiles but it crashes when I try to traverse the linked list.
I have absolutely no idea what is wrong with the implementation with local variables. What is the problem present in the Implementation with local variables?
ABOUT THE STRUCTURE OF THE PROGRAMS:
I understand that the programs are big so I'll put in something about structure of the program.
The program is structured as a menu driven program. So the initial calls to functions are in main() function
There are 3 options in main() menu - exit, traverse and insertion
Exit returns 0 to exit program while other 2 do function calls
Insertion function itself is arranged as menu-driven program.
It has 3 options - return , insert_begin and insert_end. The last 2 are function calls.
I know there are memory leaks as I haven't freed any memory but I will take care of that after I can understand the problem in the current program.
//WORKING IMPLEMENTATION USING GLOBAL VARIABLE
#include<stdio.h>
#include<stdlib.h>
#define MIN 0
#define MAX 2
#define INS_MIN 0
#define INS_MAX 2
typedef struct node
{
int data;
struct node *next;
}sll_node;
sll_node *start = NULL;
void intro()
{
system("cls");
printf("\n\tThese are the various options:\n");
printf("\n\t00 Exit");
printf("\n\t01 Traverse the list");
printf("\n\t02 Insertion into the list");
}
void insert_begin()
{
sll_node *node = malloc(sizeof(sll_node));
if(node == NULL)
{
printf("\n\tNot enough menory");
exit(-1);
}
int data;
printf("\n\tData to be entered: ");
scanf("%d", &data);
node->data = data;
node-> next = start;
start = node;
}
void insert_end()
{
sll_node *node = malloc(sizeof(sll_node));
if(node == NULL)
{
printf("\n\tNot enough menory");
exit(-2);
}
if(start == NULL)
insert_begin();
else
{
printf("\n\tData to be entered: ");
scanf("%d", &(node->data));
node-> next = NULL;
sll_node *node2;
for(node2 = start; node2->next != NULL; node2 = node2->next)
;
node2->next = node;
}
}
void insert_intro()
{
system("cls");
printf("\n\tThese are the various options:\n");
printf("\n\t00 Insertion Done");
printf("\n\t01 Insert at beginning");
printf("\n\t02 Insert at end");
}
void insertion()
{
short choice;
while(1)
{
choice = -1;
while(choice < INS_MIN || choice > INS_MAX)
{
insert_intro();
printf("\n\n\tEnter your chocie: ");
scanf("%d", &choice);
}
switch(choice)
{
case 0:
return;
case 1:
insert_begin();
break;
case 2:
insert_end();
break;
}
}
}
void traverse()
{
if(start == NULL)
printf("\n\n\tLinked list is empty");
else
{
printf("\n\n\t");
for(sll_node *node = start; node != NULL; node = node->next)
printf("%d ", node->data);
}
getch();
}
int main()
{
short choice;
while(1)
{
choice = -1;
while(choice < MIN || choice > MAX)
{
intro();
printf("\n\n\tEnter your choice: ");
scanf("%d", &choice);
}
switch(choice)
{
case 0:
return 0;
case 1:
traverse();
break;
case 2:
insertion();
break;
}
}
return 0;
}
//COMPILES BUT CRASHES - Same program but with local variable start and variable passing between functions
#include<stdio.h>
#include<stdlib.h>
#define MIN 0
#define MAX 2
#define INS_MIN 0
#define INS_MAX 2
typedef struct node
{
int data;
struct node *next;
}sll_node;
void intro()
{
system("cls");
printf("\n\tThese are the various options:\n");
printf("\n\t00 Exit");
printf("\n\t01 Traverse the list");
printf("\n\t02 Insertion into the list");
}
sll_node* insert_begin(sll_node *start)
{
sll_node *node = malloc(sizeof(sll_node));
if(node == NULL)
{
printf("\n\tNot enough menory");
exit(-1);
}
int data;
printf("\n\tData to be entered: ");
scanf("%d", &data);
node->data = data;
node-> next = start;
return node;
}
sll_node* insert_end(sll_node *start)
{
sll_node *node = malloc(sizeof(sll_node));
if(node == NULL)
{
printf("\n\tNot enough menory");
exit(-2);
}
if(start == NULL)
start = insert_begin(start);
else
{
printf("\n\tData to be entered: ");
scanf("%d", &(node->data));
node-> next = NULL;
sll_node *node2;
for(node2 = start; node2->next != NULL; node2 = node2->next)
;
node2->next = node;
}
return start;
}
void insert_intro()
{
system("cls");
printf("\n\tThese are the various options:\n");
printf("\n\t00 Insertion Done");
printf("\n\t01 Insert at beginning");
printf("\n\t02 Insert at end");
}
sll_node* insertion(sll_node *start)
{
short choice;
while(1)
{
choice = -1;
while(choice < INS_MIN || choice > INS_MAX)
{
insert_intro();
printf("\n\n\tEnter your chocie: ");
scanf("%d", &choice);
}
switch(choice)
{
case 0:
return start;
case 1:
start = insert_begin(start);
break;
case 2:
start = insert_end(start);
break;
}
}
}
void traverse(sll_node *start)
{
if(start == NULL)
printf("\n\n\tLinked list is empty");
else
{
printf("\n\n\t");
for(sll_node *node = start; node != NULL; node = node->next)
printf("%d ", node->data);
}
getch();
}
int main()
{
sll_node *start = NULL;
short choice;
while(1)
{
choice = -1;
while(choice < MIN || choice > MAX)
{
intro();
printf("\n\n\tEnter your choice: ");
scanf("%d", &choice);
}
switch(choice)
{
case 0:
return 0;
case 1:
traverse(start);
break;
case 2:
start = insertion(start);
break;
}
}
return 0;
}
You are not returning anything from insertion() function when item is added to a list. So linked list may not get constructed properly.
Probably, you should return start only when its added at the beginning, otherwise start in main() will not point to head of the list.
sll_node* insertion(sll_node *start)
{
...
switch(choice)
{
case 0:
return start;
case 1:
start = insert_begin(start);
return start; //<----- return node
break;
case 2:
start = insert_end(start);
break;
}
...
}
Change short choice to int choice.
Why does this make a difference?
Short answer is that printf("%d") expects an integer.
The long answer is "%d" describes the data type you are passing to printf as an integer (which is commonly 4 to 8 bytes), and you're giving it a datatype of short - which is commonly 2 bytes long. When your program reads the input and stores it at the pointer, &choice, it writes 4 bytes starting at that address (but only 2 were reserved). This causes a segmentation fault and will crash your program.
Here's a list to some printf documentation. You'll notice that to pass a short to printf you would write %hd instead of %d
When i compile your code on my computer, it works, but i changed "short choice" to "int choice", because scanf("%d", &choice) takes 4 bytes to write on, and when choice is short it crashes, because short has only 2 bytes, therefore stack corruption will occur, my be on your computer this corruption damage the "start" pointer.
About the crash. Change the argument start in both functions insert_begin and insert_end to sll_node ** start, and when assigning new value, use the expression *start = your-new-value. It is because you have to pass a pointer to the local variable start which is also pointer. You do not need to change function traverse.
About memory leaks, let me to point-out that when you call insert_begin from inside insert_end, the node created from insert_end is left unused. before exit() and the return in main() you should free the list.
Yes, sorry. There was another bug hard to see. It was at 2 lines where you read (choice).
short choice;
...
// It is ERROR to use "%d" with (short choice), because the stack will
// be overwritten with unsuspected results. The format specifier "%hd"
// say to compiler that (&choice) point to a short 16-bit integer,
// not 32-bit
scanf("%hd", &choice);
This is slightly different version, tested, without memory leaks.
//
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define MIN 0
#define MAX 2
#define INS_MIN 0
#define INS_MAX 2
typedef struct node
{
int data;
struct node *next;
} sll_node;
void clear_list(sll_node** start)
{
assert(start != NULL);
sll_node* node = *start;
while (node != NULL)
{
sll_node* element = node;
node = element->next;
free(element);
}
*start = NULL;
}
void intro()
{
system("cls");
printf("\n\tThese are the various options:\n");
printf("\n\t00 Exit");
printf("\n\t01 Traverse the list");
printf("\n\t02 Insertion into the list");
}
void insert_begin(sll_node** pstart)
{
sll_node* node = (sll_node*)malloc(sizeof(sll_node));
if (node == NULL)
{
printf("\n\tNot enough menory");
clear_list(pstart);
exit(-1);
}
int data;
printf("\n\tData to be entered: ");
scanf_s("%d", &data);//scanf
node->data = data;
node->next = *pstart;
// update the local variable start passed from main to point just inserted node
*pstart = node;
}
void insert_end(sll_node** start)
{
assert(start != NULL);
if (*start == NULL)
{
insert_begin(start);
}
else
{
sll_node* node = (sll_node*)malloc(sizeof(sll_node));
if (node == NULL)
{
printf("\n\tNot enough menory");
clear_list(start);
exit(-2);
}
printf("\n\tData to be entered: ");
scanf("%d", &(node->data));
node->next = NULL;
sll_node* node2;
for(node2 = *start; node2->next != NULL; node2 = node2->next)
;
node2->next = node;
}
}
void insert_intro()
{
system("cls");
printf("\n\tThese are the various options:\n");
printf("\n\t00 Insertion Done");
printf("\n\t01 Insert at beginning");
printf("\n\t02 Insert at end");
}
void insertion(sll_node** start)
{
short choice;
while(1)
{
choice = -1;
while(choice < INS_MIN || choice > INS_MAX)
{
insert_intro();
printf("\n\n\tEnter your chocie: ");
scanf("%hd", &choice);
}
switch(choice)
{
case 0:
return;
case 1:
insert_begin(start);
break;
case 2:
insert_end(start);
break;
}
}
}
void traverse(sll_node *start)
{
if (start == NULL)
printf("\n\n\tLinked list is empty");
else
{
printf("\n\n\t");
for(sll_node *node = start; node != NULL; node = node->next)
printf("%d ", node->data);
}
getch();
}
int main()
{
sll_node *start = NULL;
short choice;
while(1)
{
choice = -1;
while(choice < MIN || choice > MAX)
{
intro();
printf("\n\n\tEnter your choice: ");
scanf("%hd", &choice);
}
switch(choice)
{
case 0:
clear_list(&start);
return 0;
case 1:
traverse(start);
break;
case 2:
insertion(&start);
break;
}
}
return 0;
}
P.S. Very hard to edit! I'm new here and do not have enough experience. Wasted a lot of time to edit!

Implementing BinarySearchTree using Single Linked List

I have the below code which I am using to implement BinarySearchTree. Somehow it doesn't build the binarytree.Can anybody help what is the issue ?
typedef struct BinarySearchTree
{
struct BinarySearchTree *left;
int nodeval;
struct BinarySearchTree *right;
}
BST;
BST *root=NULL;
void addrootnode(BST *,int );
void addnode(BST *,int );
void deletenode(int );
void printnodes();
main()
{
int nodeval;
char choice;
printf("\n r->rootnode \n a->add \n d->delete \n p->print \n e->exit\n");
while (1)
{
printf("\nEnter your choice:");
scanf("%c",&choice);
switch (choice)
{
case 'r':
printf("\nEnter the root node value to add: ");
scanf("%d",&nodeval);
addrootnode(root,nodeval);
break;
case 'a':
printf("\nEnter the node value to add: ");
scanf("%d",&nodeval);
addnode(root,nodeval);
break;
case 'd':
printf("\nEnter the node value to delete: ");
scanf("%d",&nodeval);
break;
case 'p':
//printf("\n");
printnodes(root);
break;
case 'e':
exit(0);
default:
break;
}
}
getchar();
}//end of main
//addrootnode
void addrootnode(BST *ptr,int num)
{
if(ptr==NULL)
{
ptr=(BST *) malloc(sizeof(BST));
ptr->left=NULL;
ptr->nodeval=num;
ptr->right=NULL;
root=ptr;
}
}
//add node
void addnode(BST *ptr,int num)
{
if(ptr==NULL)
{
ptr=(BST *) malloc(sizeof(BST));
ptr->left=NULL;
ptr->nodeval=num;
ptr->right=NULL;
}
else if(num < ptr->nodeval )
{
addnode(ptr->left,num);
}
else
{
addnode(ptr->right,num);
}
}
//delete functionality
void deletenode(int nodeval)
{
}
//print all nodes
void printnodes(BST *ptr)
{
if (ptr)
{
printnodes(ptr->left);
printf("%d\t",ptr->nodeval);
printnodes(ptr->right);
}
}
You should not use BST *ptr as argument to addnode. You try to assign a value to it but at this time ptr is a local variable to the function addnode an does not alter the intended left or right pointer of the parent node.
Try to think about using BST **ptr instead.

Resources