Using pointers with binary trees [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Binary tree - Dereferencing pointers
I was just trying to write a simple binary search tree program where the user can insert nodes and view all the nodes in the tree in either inorder,preorder or postorder mode. My code is
#include <stdio.h>
#include <stdlib.h>
struct treenode
{
int data;
struct treenode *lchild;
struct treenode *rchild;
};
void insertnode(struct treenode **n,int d)
{
struct treenode *p=&n;
if(p==NULL)
{
// means the tree is empty
p=(struct treenode *)malloc(sizeof(struct treenode));
p->data=d;
p->lchild=NULL;
p->rchild=NULL;
}
else
{
// strat comparing the new data from root
if( d<p->data )
insertnode(((p->lchild)),d);
else
insertnode(((p->rchild)),d);
}
}
void preorder(struct treenode **n)
{
struct treenode *p=&n;
if(p==NULL)
{
printf("\nThe list is empty");
}
else
{
printf("%d",p->data);
preorder(p->lchild);
preorder(p->rchild);
}
}
void postorder(struct treenode **n)
{
struct treenode *p=&n;
if(p==NULL)
{
printf("\nThe list is empty");
}
else
{
preorder(p->lchild);
preorder(p->rchild);
printf("%d",p->data);
}
}
void inorder(struct treenode **n)
{
struct treenode *p=&n;
if(p==NULL)
{
printf("\nThe list is empty");
}
else
{
preorder(p->lchild);
printf("%d",p->data);
preorder(p->rchild);
}
}
int main(void)
{
struct treenode *root=NULL;
int choice,data;
while(1)
{
printf("\nPress 1 for inserting a node in BST fashion: ");
printf("\nPress 2 for traversing the tree in preorder fashion :");
printf("\nPress 3 for traversing the tree in postorder fashion :");
printf("\nPress 4 for traversing the tree in inorder fashion :");
printf("\nPress 5 to exit :");
printf("\nEnter your choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1: printf("\nEnter the data to be inserted:");
scanf("%d",&data);
insertnode(&root,data);
break;
case 2: preorder(&root);
break;
case 3: postorder(&root);
break;
case 4: inorder(&root);
break;
case 5: exit(0);
break;
default: printf("\nYou have enetred an invalid choice. Please try again");
}
}
return 0;
}
The program runs successfully, however after i have entered the node, the explorer detects an error and the program stops working. Is there any bug in the code ?

Spoiler:
#include <stdio.h>
#include <stdlib.h>
struct treenode {
struct treenode *lchild;
struct treenode *rchild;
int data;
} *root = NULL;
void insertnode(struct treenode **pp,int d)
{
for( ;*pp; )
{
if (d < (*pp)->data) pp = &(*pp)->lchild;
else pp = &(*pp)->rchild;
}
*pp = malloc (sizeof **pp);
(*pp)->data = d;
(*pp)->lchild = NULL;
(*pp)->rchild = NULL;
}
void preorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
printf("%d,",p->data);
if (p->lchild) preorder(p->lchild);
if (p->rchild) preorder(p->rchild);
}
void postorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
if (p->lchild) preorder(p->lchild);
if (p->rchild) preorder(p->rchild);
printf("%d,",p->data);
}
void inorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
if (p->lchild) preorder(p->lchild);
printf("%d,",p->data);
if (p->rchild) preorder(p->rchild);
}
int main(void)
{
root=NULL;
int choice,data;
while(1)
{
printf("\nPress 1 for inserting a node in BST fashion: ");
printf("\nPress 2 for traversing the tree in preorder fashion :");
printf("\nPress 3 for traversing the tree in postorder fashion :");
printf("\nPress 4 for traversing the tree in inorder fashion :");
printf("\nPress 5 to exit :");
printf("\nEnter your choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1: printf("\nEnter the data to be inserted:");
scanf("%d",&data);
insertnode( &root,data);
break;
case 2: preorder(root);
break;
case 3: postorder(root);
break;
case 4: inorder(root);
break;
case 5: exit(0);
break;
default: printf("\nYou have entered an invalid choice. Please try again");
}
}
return 0;
}

Related

Binary Search Tree, tree not updating after adding first node

I'm implementing a binary search tree in C.
void add_element(node_t **head, int element) {
if (*head == NULL) {
node_t *new_node = (node_t *) malloc(sizeof(node_t));
if (new_node == NULL) {
printf("Not enough memory\n");
return;
}
new_node->value = element;
new_node->left = NULL;
new_node->right = NULL;
*head = new_node;
} else {
node_t *dummy = *head;
if (dummy->value >= element) {
dummy = dummy->left;
add_element(&dummy, element);
} else {
dummy = dummy->right;
add_element(&dummy, element);
}
}
}
After adding the first element, the tree is not updating as when printing out only the first element appears.
The element is added when calling add_element but seems to not be updated in the original tree.
void log_tree(node_t *head) {
if (head == NULL) {
return;
}
log_tree(head->left);
printf("%d - ", head->value);
log_tree(head->right);
}
void print_menu(node_t *head) {
printf("This is a BST implementation.\n");
log_tree(head);
printf("\n");
printf("1. Add element\n");
printf("2. Remove element\n");
printf("3. Search Element\n");
printf("4. Exit\n");
}
int main() {
node_t *head = NULL;
int run = 1;
int choice, val;
while (run) {
print_menu(head);
printf("Enter your choice: ");
scanf("%d", &choice);
printf("\n");
switch (choice) {
case 1:
printf("Enter new element: ");
scanf("%d", &val);
printf("\n");
add_element(&head, val);
break;
case 2:
printf("Enter element to be removed: ");
scanf("%d", &val);
printf("\n");
remove_element(&head, val);
break;
case 3:
printf("Enter the element you want to search: ");
scanf("%d", &val);
printf("\n");
search_element(head, val);
break;
case 4:
run = 0;
break;
default:
break;
}
}
return 0;
}
This is the node_t:
struct Node {
int value;
struct Node *left;
struct Node *right;
}
typedef struct Node node_t;
I'm new to C and still confused with pointers so maybe I made some mistakes in add_element.
Updated and pasted the full code.
When you do this ...
node_t *dummy = *head;
if (dummy->value >= element) {
dummy = dummy->left;
add_element(&dummy, element);
... the recursive add_element call can modify the value of local variable dummy, but what you want to enable it to modify is (*head)->left. That dummy contains the same value as (*head)->left at that point, which it does, is an entirely different thing from it being the same object.
The same applies in the other branch.
I don't see any reason to involve dummy here. It looks like what you want is:
if ((*head)->value >= element) {
add_element(&(*head)->left, element);
} else {
add_element(&(*head)->right, element);
}

when compiling this c program "non portable pointer conversion" warning is occuring so what is the reason behind this warning?

Defination :
Create a “Queue” user-defined structure with the following data members:
A Data
A link to the next node
Perform the following operations on Simple queue using user-defined functions:
Insert an element
Remove an element
Display
Isfull
Isempty
Create a file which stores all values of list.
Code :
#include<stdio.h>
#include<stdlib.h>
struct queue{
int data;
struct queue *next;
};
typedef struct queue node;
node *start=NULL,*rear=NULL;
int choice,i;
void insert();
void rem();
void display();
void isfull();
void isempty();
int main()
{
do
{
printf("\n\t 1.Insert\n\t 2.Remove\n\t 3.Display\n\t 4.isfull\n\t 5.isempty\n\t 6. Exit\n");
printf("\n Enter the Choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
insert();
break;
}
case 2:
{
rem();
break;
}
case 3:
{
display();
break;
}
case 4:
{
isfull();
break;
}
case 5:
{
isempty();
break;
}
case 6:
{
printf("\n\t EXIT POINT ");
break;
}
default:
{
printf ("\n\t Please Enter a Valid Choice(1/2/3/4/5/6)");
}
}
}
while(choice!=6);
return 0;
}
void insert()
{
node *temp;
temp = (node*)malloc(sizeof(node));
if(temp==NULL){
printf("\n\tQueue is Full\n");
}
else{
printf("Enter a value to be inserted:");
scanf("%d",&i);
temp->data = i;
temp->next=NULL;
if(start==NULL){
start = temp;
rear = temp;
}
else{
rear->next = temp;
rear = temp;
}
}
}
void rem()
{
node *temp;
if(start==NULL)
{
printf("\n\t Queue is Empty \n");
}
else
{
temp = start;
start = start->next;
printf("\n\t The deleted element is %d",temp->data);
free(temp);
}
}
void display()
{
node *temp;
if(start!=NULL)
{
temp = start;
while(temp->next!=NULL){
printf(" %d -> ",temp->data);
temp = temp->next;
}
printf(" %d",temp->data);
}
else
{
printf("\n The Queue is empty");
}
}
void isfull()
{
node *temp;
if (rear == temp - 1)
printf("Queue Overflow \n");
else
printf("Queue is not a Overflow\n");
}
void isempty()
{
node *temp;
if (start == - 1)
printf("Queue is empty \n");
else
printf("Queue is not a empty\n");
}
Looking out for some genuine solution please anyone who can answer this one.
This is because you are comparing an integer value to pointer value you can fix it by replacing -1 to NULL in isempty function it will work perfectly without any warning. There is no need of -1 you need it when you make start and rear variables inside the structure and there data type should be int.
hope it solves your problem

why searching function does not printing the position the element i searched?

//declaing headers
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<conio.h>
//creating nodes which having data and next ptr
struct Node{ //creating node
int data;
struct Node *next;
}node;
struct Node *head;
//function declarations
void start_insertion();
void end_insertion();
void display();
void start_deletion();
void end_deletion();
void searching();
//main function
int main(){
int ch;
do{
printf("\n1: Insertion in begining\n2: Insertion in End\n");
printf("3: Deletion from beigning\n4: Deletion from End\n");
printf("5: search\n 0: Exit\n");
display();
printf("\nEnter the choice : ");
scanf("%1d",&ch);
switch(ch){
case 1: start_insertion();
break;
case 2: end_insertion();
break;
case 3: start_deletion();
break;
case 4: end_deletion();
break;
case 5: searching();
break;
case 0: exit(0);
break;
default:printf("Entered wrong choice\n");
}
//system("cls");
}while(ch!=0);
return 0;
}
//insertion from starting
void start_insertion() {
struct Node *ptr,*temp;
ptr=(struct Node*)malloc(sizeof(struct Node));
if(ptr==NULL){
printf("overflow");
}
else{
int item;
printf("Enter the data: ");
scanf("%d",&item);
if(head==NULL){
ptr->data=item;
ptr->next=NULL;
head=ptr;
}
else {
temp=head;
ptr->data=item;
ptr->next=temp;
head=ptr;
}
}
}
//insertion in end
void end_insertion(){
struct Node *ptr,*temp;
ptr=(struct Node*)malloc(sizeof(struct Node));
if(ptr==NULL){
printf("Memory overflow");
}
else{
int item;
printf("\nEnter the data : ");
scanf("%d",&item);
if(head==NULL){
ptr->data=item;
ptr->next=NULL;
head=ptr;
}
else{
temp=head;
while(temp->next!=NULL){
temp=temp->next;
}
temp->next=ptr;
ptr->data=item;
ptr->next=NULL;
}
}
}
//deletion from start
void start_deletion(){
if(head==NULL){
printf("\n************List is Empty******************\n");
}
else{
struct Node *temp;
temp=head;
head=temp->next;
free(temp);
}
}
//deletion from end
void end_deletion(){
struct Node *temp,*temp1;
temp=head;
if(temp==NULL){
printf("\n**********List is empty************\n");
}
else{
if(head->next==NULL){
head=NULL;
free(head);
}
else{
while(temp->next!=NULL){
temp1=temp;
temp=temp->next;
}
temp1->next=NULL;
free(temp);
}
}
}
//traverse the entire linkedlist display
void display(){
struct Node *temp;
temp=head;
if(temp==NULL){
printf("\nNo Node existed\n");
}
else{
while(temp!=NULL){
printf("-> %d ->",temp->data);
temp=temp->next;
}
}
}
//its not printing the position
//searching function to print the position of the element you searched.
void searching(){
if(head==NULL){
printf("List is Empty cant search");
}
else{
struct Node *temp;
temp=head;
int flag=0,p[flag],item,i=0;
printf("Enter the data you want to search: ");
scanf("%d",&item);
while(temp!=NULL){
if(temp->data==item){
p[flag]=i;
flag++;
}
i+=1;
temp=temp->next;
}
if(flag==0){ //if flag=0 the their is no data in the list
printf("no data element exist");
}
else{
for(int j=0;j<=flag;j++){
printf("*******found********%d",p[j]+1);
}
}
}
}
void searching(){
if(head==NULL){
printf("List is Empty cant search");
}
else{
struct Node *temp;
temp=head;
int flag=0,item,i=0;
int p[100];
printf("Enter the data you want to search: ");
scanf("%d",&item);
while(temp!=NULL){
if(temp->data==item){
p[flag] = i;
flag++;
}
i+=1;
temp=temp->next;
}
if(flag==0){ //if flag=0 the their is no data in the list
printf("no data element exist");
}
else{
for(int j=0;j<flag;j++){
printf("*******found********%d",p[j]+1);
}
}
}
}
i edit your search function like above.
there are 2 problems:
first, you have to init the array with number of element, your code just init the array with flag elements while flag is 0 in this line.
int flag=0,p[flag],item,i=0;
second, because your trace array p start from 0, with flag elements so you only have to go from 0 -> flag-1, so i edit your for loop to print the result:
for(int j=0;j<flag;j++)
but i think you better do other way to search in linked list:
when you go through your linked list, if you meet the data, you can print the result and break the loop.
if you meet the end of the list (NULL pointer) but still no matched data found, so that means list is not includes the data you want.
it's no need to use additional variables flag or p array to trace result.
like this:
void searching() {
if (head == NULL) {
printf("List is Empty cant search");
} else {
struct Node *temp;
temp = head;
int item, i = 0;
printf("Enter the data you want to search: ");
scanf("%d", &item);
while (temp != NULL) {
if (temp->data == item) {
printf(" found %d at %d", item, i);
break;
}
i += 1;
temp = temp->next;
}
if (temp == NULL) printf("no data element exist");
}
}
i used online compiler i tested the code with
-> 65 ->-> 45 ->-> 89 ->-> 12 ->-> 8 ->-> 45 ->
Enter the choice : 5
Enter the data you want to search: 45
*******found********2*******found********6
add it work but just remove the = here
for(int j=0;j<flag;j++){ //j<flag not j<=flag
printf("*******found********%d",p[j]+1);
}

How can I add Lchild and Rchild to my existing nodes?

I have the following C program that adds Nodes to a tree and then the user can select a sorting method. How can I modify the program in a manner that will allow me to add a LChild and RChild to every node? Any help is highly appreciated since I am completely new to BSTs.
Writiong this because apparently my post is mostly code
Code:
#include <stdio.h>
#include <stdlib.h>
struct treenode {
struct treenode *lchild;
struct treenode *rchild;
int data;
} *root = NULL;
void insertnode(struct treenode **pp,int d)
{
for( ;*pp; )
{
if (d < (*pp)->data) pp = &(*pp)->lchild;
else pp = &(*pp)->rchild;
}
*pp = malloc (sizeof **pp);
(*pp)->data = d;
(*pp)->lchild = NULL;
(*pp)->rchild = NULL;
}
void preorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
printf("%d,",p->data);
if (p->lchild) preorder(p->lchild);
if (p->rchild) preorder(p->rchild);
}
void postorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
if (p->lchild) preorder(p->lchild);
if (p->rchild) preorder(p->rchild);
printf("%d,",p->data);
}
void inorder(struct treenode *p)
{
if(p==NULL)
{
printf("\nThe list is empty");
return;
}
if (p->lchild) preorder(p->lchild);
printf("%d,",p->data);
if (p->rchild) preorder(p->rchild);
}
int main(void)
{
root=NULL;
int choice,data;
while(1)
{
printf("\nPress 1 for inserting a node in BST fashion: ");
printf("\nPress 2 for traversing the tree in preorder fashion :");
printf("\nPress 3 for traversing the tree in postorder fashion :");
printf("\nPress 4 for traversing the tree in inorder fashion :");
printf("\nPress 5 to exit :");
printf("\nEnter your choice: ");
scanf("%d", &choice);
switch(choice)
{
case 1: printf("\nEnter the data to be inserted:");
scanf("%d",&data);
insertnode( &root,data);
break;
case 2: preorder(root);
break;
case 3: postorder(root);
break;
case 4: inorder(root);
break;
case 5: exit(0);
break;
default: printf("\nYou have entered an invalid choice. Please try again");
}
}
return 0;
}
when a new value added to BST,then it check the conditions such that if value ">" the current node value then its we move to the right child of the node and if value "<" then we move to the left child of the node,we do this untill we get to leaf node.
As for your case,just change for condition with while conditions and check if it works.
void insertnode(struct treenode **pp,int d)
{
while((*pp)->data == NULL)
{
if (d < (*pp)->data)
pp = &(*pp)->lchild;
else
pp = &(*pp)->rchild;
}
*pp = malloc (sizeof **pp);
(*pp)->data = d;
(*pp)->lchild = NULL;
(*pp)->rchild = NULL;
}

Doubly Linked List Delete Function Error

I have written the following program but the problem is in Delete function.Whenever i am trying to delete the value at first position.The whole list is lost don't know why.If i try to display list after that then some garbage values are printed.The function is working perfectly for other positions.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
struct Student
{
int rno;
char name[20];
struct Student *next;
struct Student *prev;
};
void Display(struct Student *head)
{
assert(head!=NULL);
while(head!=NULL)
{
printf("%d\t%s\t",head->rno,head->name);
head=head->next;
}
}
struct Student *Insert(struct Student *head,const int position,const int rno,const char name[])
{
//printf("%s\n",__FUNCTION__);
struct Student *temp=(struct Student *)malloc(sizeof(struct Student));
struct Student *traverse=head;
int pos=position;
if(temp==NULL)
exit(-1);
temp->rno=rno;
strcpy(temp->name,name);
temp->next=NULL;
temp->prev=NULL;
// printf("%s\n",__FUNCTION__);
if(pos==1)
{
if(head==NULL)
{
head=temp;
}
else
{
temp->next=head;
head->prev=temp;
head=temp;
}
}
else
{
for(traverse=head,pos=position;traverse->next!=NULL&&pos-2!=0;traverse=traverse->next,pos--);
if(traverse==NULL || pos-2!=0)
{
printf("Invalid Position");
}
else
{
temp->next=traverse->next;
if(temp->next!=NULL)
temp->next->prev=temp;
temp->prev=traverse;
traverse->next=temp;
}
}
return head;
}
void DeleteAll(struct Student *head)
{
struct Student *temp=head;
while(temp->next!=NULL)
{
head=head->next;
free(temp);
temp=head;
}
free(temp);
}
void Delete(struct Student *head,int pos)
{
assert(head!=NULL);
struct Student *temp=head;
struct Student *traverse=head;
int position=pos;
if(position==1)
{
if(head->next!=NULL)
head=head->next;
head->prev=NULL;
temp->next=NULL;
free(temp);
}
else
{
while(traverse->next!=NULL&&position-1!=0)
{
traverse=traverse->next;
position--;
}
if(traverse==NULL || position-1!=0)
{
printf(".............Invalid position..........\n");
}
else
{
traverse->prev->next=traverse->next;
if(traverse->next)
traverse->next->prev=traverse->prev;
}
}
}
struct Student *CreateStudentList(const int no_of_students)
{
struct Student *head=NULL;
int i;
int rno;
char name[20];
for(i=0;i<no_of_students;i++)
{
printf("Enter roll number and name:");
scanf("%d%s",&rno,name);
head=Insert(head,i+1,rno,name);
}
return head;
}
void SimulateDoublyLinkedList()
{
struct Student *cdscpp2013=NULL;
int no_of_students;
int choice,rno,position;
char name[20];
while(choice!=5)
{
if(NULL==cdscpp2013)
{
printf("Enter number of students:");
scanf("%d",&no_of_students);
cdscpp2013=CreateStudentList(no_of_students);
}
else
{
printf("\nMenu Operations\nPress 1 for Insert\nPress 2 for Delete\nPress 3 for DeleteAll\nPress 4 for Display\nPress 5 for Exit\nEnter your choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter roll number and name to ininsert:");
scanf("%d%s",&rno,name);
printf("Enter position to insert:");
scanf("%d",&position);
cdscpp2013=Insert(cdscpp2013,position,rno,name);
break;
case 2:
printf("Enter position to delete:");
scanf("%d",&position);
Delete(cdscpp2013,position);
break;
case 3:
DeleteAll(cdscpp2013);
break;
case 4:
Display(cdscpp2013);
break;
case 5:
exit(1);
default:
printf("Invalid choice....Please Enter proper option.....");
}
}
}
}
int main()
{
SimulateDoublyLinkedList();
}
When you remove the first element of a list, the caller must update its reference to the list. So your Delete function must return the pointer to the first element of the resulting list.
In this kind of operation I also find useful to use pointers to pointers... this would simplify a lot your code.
try this for delete this should work -
as temp = head , the temp->next =null will make the whole list disappear
//just removed temp->next = null;
if(position==1) {
if(head->next!=NULL)
head=head->next;
head->prev=NULL;
free(temp);
}
Edited --
make delete function to return the head pointer and in the switch case use this
cdscpp2013=Delete(cdscpp2013,position);
instead of this
Delete(cdscpp2013,position);
then change the same for deleteall function - it should work :)

Resources