I tried to search a tree node with a specific value in a binary search tree.
So I used recursion, but it didn't worked well.
I want to know what is wrong with the function.
Someone said I should return the function when I call it in itself.
It actually worked, but I don't understand why. Can someone explain to me how recursion really works and what if the return type is void?
Thank you!
typedef struct node
{
struct node* left;
struct node* right;
int val;
}treeNode;
int searchTree(treeNode *T, int key, treeNode *T1, treeNode** p)
{
if(!T)
{
*p=T1;
return 0;
}
else if(T->val==key)
{
*p=T;
return 1;
}
else if(T->val<key)
{
searchTree(T->right,key,T,p);
}
else
{
searchTree(T->left,key,T,p);
}
return 1;
}
you missed to return the value of the recursive call
if you need to do a recursive call this is not for nothing ;-)
int searchTree(treeNode *T, int key, treeNode *T1, treeNode** p)
{
if(!T)
{
*p=T1;
return 0;
}
else if(T->val==key)
{
*p=T;
return 1;
}
else if(T->val<key)
{
return searchTree(T->right,key,T,p);
}
else
{
return searchTree(T->left,key,T,p);
}
}
Note that because the recursion is terminal the compiler can remove it and produce a loop ...and you can do that by yourself too ;-)
Related
I apologize for the confusing title and I hope my explanation will help clear up the fog of confusion that is most likely taking place in your mind right now. So today I decided to try and create a binary tree program that was capable of inserting and searching for certain numbers. Now when I had finished my search function and decided to test it I got a Segmentation Fault. I then had the current IDE I was using run GDB to find the root of my problem. GDB then returned with the following message:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400634 in search (num=503, dt=0x0) at main.c:39
39 if(num < dt->data) {
what I had seem to notice is that for some strange reason my dt(which is a struct which the function uses to navigate threw the binary tree)pointer variable had been zeroed out even though the variable I had entered into the function is pointing to a allocated buffer. This has left me in confusion for quite a while now and hopefully someone can assist me on figuring out the root of this problem.
My Code:
#include <stdio.h>
#include <stdlib.h>
#define ROOT_NODE 500
typedef struct _DNode {
int data;
struct _DNode *right;
struct _DNode *left;
}Node;
Node *InitNode();
void insert(int num, Node *dt);
int search(int num, Node *dt);
void insert(int num,Node *dt) {
if(num <= dt->data) {
if(dt->left == NULL) {
dt->left = InitNode(num);
}else {
insert(num,dt->left);
}
}else {
if(dt->right == NULL) {
dt->right = InitNode(num);
}else {
insert(num,dt->right);
}
}
}
int search(int num,Node *dt) {
if(num < dt->data) {
if(dt->left == NULL) {
return -1;
}else {
return search(num,dt->left);
}
}else {
if(num > dt->data) {
if(dt->right == NULL) {
return -1;
} else {
return search(num,dt->left);
}
}
if(num == dt->data) {
return 0;
}
}
}
Node *InitNode(int num) {
Node *TNode = (struct _DNode *)malloc(sizeof(Node));
TNode->right = NULL;
TNode->left = NULL;
TNode->data = num;
return (TNode);
}
int main()
{
Node *root = InitNode(ROOT_NODE);
root->data = ROOT_NODE;
insert(507,root);
insert(503,root);
printf("%i",search(503,root));
}
Bug!
The problem in your code is you are calling the passing the wrong node in the tree. So it will be
return search(num,dt->left);
In this place
if(dt->right == NULL) {
return -1;
} else {
return search(num,dt->left);
^^^^^^
}
Alternative Implementation
In the code you didn't take advantage of the recursive code. You have repeated same unnecessary code for left and right subtree which shouldn't be the case.
Correct code can be as simple as this
int search(int num,Node *dt) {
if(dt == NULL)
return -1;
else if(dt->data == num)
return 0;
else if(dt->data >= num)
return search(num,dt->left);
else
return search(num,dt->right);
}
Also there is one thing about insertion in your code. You will never in your setup insert a node to an empty tree. And the tree insertion will work correctly only if the root is not NULL. So the insertion code should be
Node * insert(Node *p, int num){
if(p == NULL)
return initNode(num);
else if(num <= p->data)
return p->left = insert(p->left,num);
else
return p->right = insert(p->right,num);
}
And call it like
root = insert(root, num);
In:
if(dt->right == NULL) {
return -1;
} else {
return search(num,dt->left);
}
you've probably meant:
...
return search(num,dt->right);
...
I'm sure I'm making some silly mistake, hope somebody can help me out and clear some of my basic concepts.
Here's my code to create and print a basic BST in C:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct bst
{
int value;
struct bst *left;
struct bst *right;
}T;
T *temp=NULL, *newnode;
T *tree; // had globally declared as NULL previously
T* createnode(int val)
{
newnode=(T*)malloc(sizeof(T));
if(newnode==NULL)
{
printf("Memory not allocated! \n");
}
else
{
newnode->value=val;
newnode->right=NULL;
newnode->left=NULL;
}
return newnode;
}
T * insert_tree(T *tree, int val)
{
if(tree==NULL)
{
newnode=createnode(val);
tree=newnode;
return tree;
}
if (val < tree->value)
{
tree->left=insert_tree(tree->left,val);
}
else if(val > tree->value)
{
tree->right=insert_tree(tree->right, val);
}
return tree;
}
void display_preorder(T *tree) //changed to accept parameter
{
if(tree)
{
printf("%d \n", tree->value);
display_preorder(tree->left);
display_preorder(tree->right);
}
}
int main(void)
{
insert_tree(tree,34);
insert_tree(tree,45);
insert_tree(tree,88);
insert_tree(tree,87);
display_preorder();
return 0;
}
It runs and executes without error, but, the output screen is blank.
Can somebody please point out the errors and mistakes?
Thank You.
The problem is in the insert_tree function.
Because your function gets only a pointer of a tree and not a pointer to a pointer you returned the value.
So, in the main you should place the tree equal to the function.
Your function gets the tree pointer by value and not by reference.
like this:
int main(void)
{
tree = insert_tree(tree, 34);
tree = insert_tree(tree, 45);
tree = insert_tree(tree, 88);
tree = insert_tree(tree, 87);
display_preorder(tree);
getchar();
return 0;
}
I am trying to write a code for finding distances between root and any node in binary tree. If the value of the node I am looking for is not in tree, I'll add it in tree and write its depth. I tried to write a code but somehow for root i get correct answer (depth=0) and for anything else I get value of depth = 1. I have been looking in code for quite a while now, so maybe you guys can help. Much appreciated.
#include <stdio.h>
#include <stdlib.h>
typedef struct b_tree t;
struct b_tree {
int value;
struct b_tree * right;
struct b_tree * left;
};
int add(t **root, t *bam, int pom) {
if ((*root) == NULL) {
*root = bam;
return pom;
}
else {
if((*root)->value == bam->value){
return pom;
}
else if((*root)->value > bam->value) {
pom++;
add(&(*root)->left, bam, pom);
}
else if ((*root)->value < bam->value) {
pom++;
add(&(*root)->right, bam, pom);
}
}
return pom;
}
int main() {
t *akt, *root = NULL;
int x=1, pom=0, depth;
while (x!=0){
scanf("%d", &x);
pom=0;
akt = (t *)malloc(sizeof(t));
akt->left = akt->right = NULL;
akt->value = x;
depth = add(&root, akt, pom);
printf("%d\n", depth);
}
return 0;
}
When debugging, the code gets in a unusual cycle (??). if pom is the value represented as my depth from root to node, what it does is, it gets to the correct answer (depth of node is 3, pom=3), but when I try to return pom; for unknown reason (to me) pom is lowered always to 1. Thanks for your help!
You are discarding the values returned by recursive calls to add(). Change the calls to:
return add(&(*root)->left, bam, pom);
...
return add(&(*root)->right, bam, pom);
As the title declares, I have a problem concerning an ordered list;
the line where the program crashes is signed in the code below; anyone have idea of where I'm wrong?
Here the job.h header:
typedef struct
{
char stringa[DIM];
unsigned int priority;
} Job;
Here the link declaration (I know it's weird, but my professor want this):
typedef struct QUEUEnode *link;
And here the incriminated module:
#include "ordinate_list.h"
#include <stdlib.h>
#include <stdio.h>
struct QUEUEnode
{
link next;
Job job;
};
void QUEUEinit(Job);
void QUEUEput_ordered(Job a);
void QUEUEfind_link(link b, Job a);
void QUEUElink(link upper, link bottom, Job a);
void print_list_(link, int);
link head=NULL;
int QUEUED_nodes=0;
void add_QUEUEnode(Job a)
{
if(QUEUED_nodes==0)
{
printf("Coda iniziallizata...\n\n");
QUEUEinit(a);
}
else
{
QUEUEput_ordered(a);
}
}
void QUEUEinit(Job a) //OK
{
head = malloc(sizeof(struct QUEUEnode));
head->next=NULL;
head->job=a;
QUEUED_nodes++;
}
void QUEUEput_ordered(Job a)
{
if(head->job.priority<=a.priority)
{
QUEUElink(NULL, head, a);
}
else
{
QUEUEfind_link(head, a);
}
}
void QUEUEfind_link(link b, Job a)
{
if(b->next==NULL)
{
QUEUElink(b, NULL, a);
}
else if((b->job.priority > a.priority) && (b->next->job.priority < a.priority))
{
QUEUElink(b, b->next, a);
}
else QUEUEfind_link(b->next, a);
return;
}
void QUEUElink(link upper, link bottom, Job a)
{
link tmp;
tmp = malloc(sizeof(struct QUEUEnode));
tmp->job=a;
if(upper==NULL)
{
tmp->next=head;
head=tmp;
}
else if(bottom==NULL)
{
bottom->next=tmp;
tmp->next=NULL;
}
else
{
upper->next=tmp; //HERE! DAMN BUG
tmp->next=bottom;
}
QUEUED_nodes++;
}
Job QUEUEget_top()
{
Job a;
link tmp=head;
a=head->job;
head=head->next;
free(tmp);
QUEUED_nodes--;
return a;
}
As you can see from the code, the program crashes at an unusual line. The only thing I haven't tried is to change the priority of the jobs, putting the second before the head and not after; Do it worth the try?
Well, you haven't provided ordinate_list.h, and your posted code doesn't have a main(), so we can't possibly tell you for certain what the problem is. I can, however, tell you for certain what a problem is... in your QUEUElink() function, you have a guaranteed failure right here:
else if(bottom==NULL)
{
bottom->next=tmp;
tmp->next=NULL;
}
If bottom is equal to NULL, I can assure your with absolute, utter certainty that bottom->next=tmp; is impossible, and will segfault.
i build this interface for List in c,i insert to the list pointer of array of struct,
now i want to print all the fields of the struct,how can i do that?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
typedef struct element {
void *item;
struct element *next;
} Element;
typedef Element* position;
typedef Element* List;
typedef struct strc
{
int row,col,value;
} Strc;
List initList()
{
Element *ls=malloc(sizeof(Element));
if(ls)
ls->next=NULL;
else
ls=NULL;
return ls;
}
position insertToList(position p, void *item)
{
position newp=malloc(sizeof(Element));
if(newp)
{
newp->next=p->next;
p->next=newp;
newp->item=item;
//p=p->next;
}
else newp=NULL;
return newp;
}
void *retriveFromList(position p) { return p->item; }
position Next(position p) { return (position)p->next; }
int isEmpty(List ls) { return ls->next==NULL; }
void freeList(List ls)
{
position pos=ls->next;
while(ls->next!=NULL)
{
pos=ls->next;
ls->next=pos->next;
free(pos);
}
}
void puts(List *ls)
{
Position p=*ls;
Strc *tmp;
int i;
for(i=0;i<10;i++)
{
tmp=(Strc *)malloc(sizeof(strc));
tmp->row=i;
tmp->col=i+1;
tmp->value=i+2;
p=insertToList(p,tmp);
}
}
void print_list(List ls)
{
position p=ls->next;
while(p!=NULL)
{
printf("%3d\n",*((int*) retriveFromList(p)));
p=Next(p);
}
}
void main()
{
List ls=initList();
puts(&ls);
print(ls);
}
So, my C isn't grand
But, it seems like there are a ton of little typos that are going to eat you as you get this to run. One of the biggest being that puts() is already defined in stdio.h.
First, this thing doesn't compile for me, so working through all the compiler errors got me pretty far. Your puts function also was missing a closing bracket. I renamed it to putv() and changed it to be the following.
void putv(List *ls)
{
position p=*ls;
Strc *tmp;
int i;
for(i=0;i<10;i++)
{
if(tmp=(Strc *)malloc(sizeof(Strc)))
{
tmp->row=i;
tmp->col=i+1;
tmp->value=i+2;
p=insertToList(p,tmp);
}
}
}
The second issue was that your main function was not calling print_list(), but instead calling plain print().
void main()
{
List ls=initList();
putv(&ls);
print_list(ls);
}
This doesn't solve all of your problems
Mostly because I don't think it's printing what you want, but I'm going to leave a little bit for you to figure out.