Recursive code for a tree function? - c

I have a function that returns the first node of a tree,
node* primeiro(tree r){
while(r->left != NULL){
r = r->left;
}
return r;
}
BTW, the percuss is made in order. So the function returns the leftmost leaf of the tree and the function presumes that the tree is not empty. How can I implement this in a recursive way?
node* primeiro (tree r) {
while (r->left != NULL) {
r = primeiro (r->left);
}
return r;
}
This is not working.

The problem is in using while. You need simple recursion termination condition.
node* primeiro (tree r) {
if (r->left != NULL) {
r = primeiro (r->left);
}
return r;
}

Instead of using condition r->left != NULL for while loop, check it for true or false. (that will be base condition for the termination of recursion).

When we speak of "recursive functions", we usually mean "functions that use recursion to loop"...
Both of your functions are using while to loop. You should focus on transforming that while loop into a recursive function call.
Consider this loop:
int fubar(int x) {
while (x > 0) {
x--;
}
return x;
}
It transforms into this:
int fubar(int x) {
if (x > 0) {
return fubar(x - 1);
}
return x;
}
Notice how similar the two are. The differences are:
You're changing x not directly but by passing a different value of x in
Your loop test is in an if statement, not while...
Again, you're not looping using while; instead you should be calling fubar again, passing in a new value and returning its result.
Important note: There could be significant benefits to ensuring every recursive function call is followed immediately by a return (without any intermediate calculations required).

When iteration is being replaced with recursion, it may be easier to derive the right code by beginning with the infinite recursive loop:
node* primeiro(tree r){
/* What goes in the recursive loop body? */
return primeiro(r);
}
You can now ask under what would the next value of the iteration, and when does the loop stop. The next value is pretty straight forward.
node* primeiro(tree r){
/* When does the recursive loop stop? */
r = r->left;
return primeiro(r);
}
From the while loop logic, the loop stops when r->left is NULL. At that point, you would return r.
node* primeiro(tree r){
if (r->left == NULL) return r;
r = r->left;
return primeiro(r);
}

Related

does this (existe element ) function work properly using recursion

i created a function to detect if a word does exist in a linked list with recursion.
i wanted to know if its correct or not .
bool does_exist_in_list(index *head,char word[25]){
while( head != NULL ){
//to detect the first element
if(strcmp(word,head->word) == 0)
return true;
else{
//to go to the next element
return does_exist_in_list(head->next,word);
}
}
}
because im using it in a long code so i dont know if there is a problem in it
The while loop is misleading, as the function always returns during the first iteration.
Additionally, if head is NULL, the function fails to return a value at all, invoking Undefined Behaviour.
bool does_exist_in_list(index *head, char word[25])
{
if (!head)
return false;
if (0 == strcmp(word, head->word))
return true;
return does_exist_in_list(head->next, word);
}

bitwise right shift affecting another short

I am using bitwise operators to shift the binary value of shorts within a linked list. The function is recursive and after an arbitrary number of occurrences, my right shift seems to affect the value of a short in the next link despite me not pointing to this link at all at this point of the function. Here is my code :
static void move_right(t_tetri *piece) {
int i;
i = 0;
piece->x_offset++;
while (i < piece->height) {
piece->shape[i] = piece->shape[i] >> 1;
i++;
}
}
int ft_solve(t_map *map, t_tetri *list) {
if (list == NULL) return (1);
while (list->y_offset + list->height <= map->size) {
while (list->x_offset + list->width <= map->size) {
if (put_tetri(map, list)) {
set_piece(map, list);
if (ft_solve(map, list->next)) return (1);
else unset_piece(map, list);
}
move_right(list);
}
reset_piece(list);
}
list->y_offset = 0;
return (0);
}
piece->shape is an array containing 4 short but I'm mostly concerned about the first of these here. In certain cases (not all) when I go through the move_right function the value of piece->next->shape[0] is shifted in the same way, which poses a big problem for the next recursion of ft_solve.
Would anyone have any idea?
I can post more of my code if necessary, I'm not really used to ask questions here so if you need more information I'm ready to add it.

Function to balance a search tree

So I need some help on this since I'm reading from a file and inserting into a list and a tree for search purposes, this function is not saving all the nodes, it loses the information while running.
fe=left child
fd=right child
NodeCount returns how many nodes are in the Tree and the rotate functions are working properly
TREE *rotate left(TREE *A) //right just replace fe for fd:
{
ARVORE *aux;
aux=A->fd;
A->fd=aux->fe;
aux->fe=A;
return A;
}
the balance function returns 1 if the tree is balanced and 0 if not
TREE *balances (TREE *A)
{
TREE *aux = A;
if(aux == NULL)
return A;
while(!balance(aux))
{
if((NodeCount(aux->fe) - NodeCount(aux->fd)) > 1)
aux=rotateright(aux);
if((NodeCount(aux->fd) - NodeCount(aux->fe)) > 1)
aux=rotateleft(aux);
return aux;
}
return A;
}
output :
before balances :0
01gwztbs0d#yahoo.com
2v7t5k72fb#clix.pt
2v7t5k72fb#clix.pt
3ahf#sapo.pt
bysws#clix.pt
cop8m5#clix.pt lost
ibnor#yahoo.com lost
lglkge#clix.pt lost
sck0z#yahoo.com lost
After Balances
01gwztbs0d#yahoo.com
2v7t5k72fb#clix.pt
2v7t5k72fb#clix.pt
3ahf#sapo.pt
bysws#clix.pt
Equi:1
Your problem is logical. Your if-statements are not logically connected with each other and the conditions overlap. As a result aux is overwritten with all the statements of the second if and then returned as such.
Example: first aux = cop8m5#clix.pt; then aux = 01gwztbs0d#yahoo.com; and 01gwztbs0d#yahoo.com is returned.
If you look closely, you would see that what is missing, is exactly the right partial subtree (all elements greater than the root). As it looks it is an inorder traversal, so therefore the root must be bysws#clix.pt. From here you can easily see it yourself.
The quickest solution is to put one return aux; in the body of each if-statement:
while(!balance(aux)) {
if ((NodeCount(aux->fe) - NodeCount(aux->fd)) > 1) {
aux=rotateright(aux);
return aux;
}
if ((NodeCount(aux->fd) - NodeCount(aux->fe)) > 1) {
aux=rotateleft(aux);
return aux;
}
}

pointers and linked list in C- unexpected behavior of program

I recently started programming in C, and I've been working in a linked list program for a while. Now, the program is about having a profile in which you will register movies you watch and then save them in a .txt file. the trouble comes with the movie getting into the list. when I try to print it, the fields will show empty, as if I weren't assigning the pointers properly, but the fact is that the program KNOWS that I stacked a movie in my profile. I know it's a hard question to ask, any help would be appreciated. I'll show here the Insertmovie function, where I think there might be the problem, and the moviecopy function(I tested that function and does not work itself, although I doubt I did something wrong there):
int stacknewmovie (movie* p, list* l){
if(!p || !l){
return 0;
}
node* n;
n=newnode();
if(!n){
return 0;
}
insertnodeinfo(n, p);
n->next=NULL;
if(l->first==NULL){
l->first=n;
return 1;
}else{
n->next=l->first;
l->first=n;
return 1;
}
}
Here the moviecopy:
int moviecopy(movie* pel2,movie* pel1){
if(!pel1 || !pel2){
return NULL;
}else{
pel2=pel1;
return 1;
}
}
Again, thanks for taking your time. I didn't know how to show my problem better, as the compiler doesn't even warns me about anything.
node* insertnodeinfo(node* n, movie* p){
if(!p || !n){
return NULL;
}else{
moviecopy(n->info, p);
return n;
}
}
int stacknewmovie (movie* p, list* l){
if(!p || !l){
return 0;
}
node* n;
n=newnode();
if(!n){
return 0;
}
insertnodeinfo(n, p);
n->next=NULL;
if(l->first==NULL){
l->first=node; //problem here replace "node" by "n"??
return 1;
}else{
n->next=l->first;
l->first=n;
return 1;
}
as I did in the comment replace "node" by "n" first (I suppose that you want to write "n" not "node")
I think it is not a linked list because:
n->next=l->first; //this made the list a circular linked list
l->first=n; //Here is the problem I think
Because always the new node becomes the first node in the list, Is this that you want?

C - Removing int messes up queue

I have a struct containing an array of integers and an int ("rear") showing the end of the queue. I have some functions, e.g. add(), remove() and print().
The remove() function should move all items forward (effectively deleting the arr[0], replacing it by arr[1], but it does not work.
if my array looks like 111,222,333,444 and I call remove(), the result looks something like 112,223,334, etc.
So far I was able to solve all the often really frustrating problems, mainly related to Java, but this C problem I just do not understand at all. I hope for some input from you. Thanks.
The relevant part of code:
void remove( struct queue *q )
{
int i;
system ("cls");
if ( q->rear > 0)
{
printf("\n\n%d has been removed\n\n", q->rank[0]);
q->rear--;
for ( i = 0; i < q->rear; i++)
{
q->rank[i] = q ->rank[i]++;
printf(rank[i])
}
q->rank[(q->rear +1)] = NULL;
}
else
{
printf("\n\nThe queue is empty\n\n");
}
}
The line
q->rank[i] = q ->rank[i]++;
should be
q->rank[i] = q ->rank[i+1];
otherwise you're incrementing i twice in the loop.

Resources