Print reversely the elements of a list using recursion - c

I want to print reversely the elements of a list using recursion, but I get an execution error !
Can someone help?
typedef struct node
{
int val;
struct node* next;
}node;
typedef struct list
{
node* head;
}list;
void display(list L)
{
if(L.head == NULL) return;
L.head= L.head->next;
display(L);
printf("%d\t",L.head->val);
}

void display(node *N){
if(N != NULL){
display(N->next);
printf("%d\t",N->val);
}
}
and in main:
int main (void)
{
//...
display (L.head);

Instead of using :
typedef struct list
{
node* head;
}list;
you can simply pass the "node n" instead, and call it recursively using n->next, as follows:
void display(node *n){
if(n != NULL){
display(n->next);
printf("%d\t",n->val);
}
}
And then call that method from the outside as follows:
display(node->head);
or
display(node.head);
Depending on how you have allocated the structure "node".
Side Note:
I would actually renamed your structures to:
typedef struct List
{
int val;
struct List* next;
}List;
and then call:
void display(List *l){
if(l != NULL){
display(l->next);
printf("%d\t",l->val);
}
}
IMO it better expresses the use-case in hand.
A Full example:
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct List
{
int val;
struct List* next;
}List;
void display(List *l){
if(l != NULL){
display(l->next);
printf("%d\t",l->val);
}
}
List *addElement(List *l, int val){
if(l == NULL){
List *node = malloc(sizeof(List));
node->val = val;
node->next = NULL;
return node;
}
else
l->next = addElement(l->next, val);
return l;
}
void freeList(List *l){
if(l != NULL){
freeList(l->next);
free(l);
}
}
int main(){
List *l = NULL;
l = addElement(l, 1);
l = addElement(l, 2);
l = addElement(l, 3);
l = addElement(l, 4);
l = addElement(l, 5);
display(l);
freeList(l);
}
OUTPUT:
5 4 3 2 1

Related

How can I add numbers from a given array to a linked list without allowing duplicates?

I gotta write a function that takes the number from a given array and creates a linked list with them without allowing duplicates, my code works for adding the numbers but when I print the list I still get duplicate 4, it's like the function doesn't check if the number is already in the list and I can't find what's wrong.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} SNode;
typedef SNode *TNode;
void makeList(int arr[], int len, TNode *head);
void printList(TNode head);
void main() {
TNode head = NULL;
int array[5] = { 1, 2, 4, 4, 8 };
makeList(array, 5, &head);
printList(head);
}
void makeList(int arr[], int len, TNode *head) {
TNode tmp1, tmp2 = *head;
int i, j;
for (i = 0; i < len; i++) {
if (tmp2 == NULL) {
tmp1 = (TNode)malloc(sizeof(SNode));
tmp1->data = arr[i];
tmp1->next = *head;
*head = tmp1;
}
while (tmp2 != NULL) {
if (tmp2->data != arr[i]) {
tmp1 = (TNode)malloc(sizeof(SNode));
tmp1->data = arr[i];
tmp1->next = *head;
*head = tmp1;
}
tmp2 = tmp2->next;
}
}
}
void printList(TNode head) {
TNode tmp = head;
while (tmp != NULL) {
printf("%d ", tmp->data);
tmp = tmp->next;
}
}
Never ever hide pointers behind the typedefs. It is a very bad practice.
I do not think that you need great performance, you can traverse the linked list
Use the correct type for sizes
Use object not types in sizeofs
Split the problem into smaller tasks (functions)
void main is wrong.
Do not cast the result of the malloc. If the code does not compile it means that you compile it using a C++ compiler wich is not correct.
Avoid double pointers and side effects if possible. Use function return values (instead of void func)
typedef struct Node {
int data;
struct Node* next;
} SNode;
SNode *makeList (const int arr[], size_t len, SNode *head);
void printList (SNode *head);
int main(void)
{
SNode *head, *tmp;
int array[5] = {1,2,4,4,8};
int array2[5] = {6,2,4,7,9};
head = makeList (array, 5, NULL);
if(head) printList (head);
printf("-------------------------\n");
tmp = makeList (array2, 5, head);
if(tmp)
{
head = tmp;
printList (head);
}
/* free the list */
}
int isInList(const int val, const SNode *head)
{
int result = 0;
while(head)
{
if(head -> data == val)
{
result = 1;
break;
}
head = head -> next;
}
return result;
}
SNode *add(int val, SNode *last)
{
if(!last) last = malloc(sizeof(*last));
else
{
last -> next = malloc(sizeof(*last));
last = last -> next;
}
if(last)
{
last -> data = val;
last -> next = NULL;
}
return last;
}
SNode *findLast(const SNode *head)
{
if(head)
{
while(head -> next) head = head -> next;
}
return (SNode *)head;
}
SNode *makeList (const int arr[], size_t len, SNode *head)
{
SNode *last = findLast(head);
while(len--)
{
if(!isInList(*arr, head))
{
last = add(*arr, last);
if(!head) head = last;
if(!last) break;
}
arr++;
}
return head;
}
void printList(SNode *head)
{
while(head) {printf("%d\n", head -> data);head = head -> next;}
}
https://godbolt.org/z/1Wssf6Gz9

Doubly linked list not working

I am trying to sort a doubly linked list in ascending order. I've gone trough the code again and again, and I can't find any logical flaws with it, so I assume the problem is elsewhere. When I try to print the sorted list, the console returns 0 without printing anything (the print function is not to blame, since it has already been tested)
Here is the code I am currrently running:
typedef struct dados_temp{
float temp;
float incerteza;
char pais[100];
char cidade[100];
float angle;
int hemisferio;
int dia;
int mes;
int ano;
} dados_temp;
typedef struct Node{
dados_temp payload;
struct Node *next;
struct Node *prev;
} Node;
//receives the original head pointer
//returns sorted list's head pointer
Node** SortDate(struct Node** head)
{
struct Node *i, *j;
for( i = head; i != NULL; i = i->next )//iterates over the entire list
{
//if the data value of the next node is bigger
if ( i->payload.ano > i->next->payload.ano )
{
//swaps the data value between i and i->next
//SwapNodes was tested and it is working
SwapNodes(i, i->next);
//the current value of i->next (former value of i)
//is compared to all the previous values
//and keeps swapping until a smaller value is found
for (j = i->next; j->payload.ano < j->prev->payload.ano;)
{
SwapNodes(j, j->prev);
}
}
}
return head;
}//sort
I know there probably are easier ways to sort doubly linked list, but I'm trying to figure out why this one doesn't work.
Thank you in advance!
EDIT:
showing all the involved functions:
#include <stdio.h>
#include <stdlib.h>
typedef struct dados_temp{
float temp;
float incerteza;
char pais[100];
char cidade[100];
float angle;
int hemisferio;
int dia;
int mes;
int ano;
} dados_temp;
typedef struct Node{
dados_temp payload;
struct Node *next;
struct Node *prev;
} Node;
Node * CreateCitiesList();
Node * CreateCountriesList();
Node * Intervalos(struct Node*, int[]);
void PrintBack(struct Node*);
struct Node* CreateNode (dados_temp x)
{
struct Node* NewNode = (struct Node*)malloc(sizeof(struct Node));
NewNode->payload = x;
NewNode->next = NULL;
NewNode->prev = NULL;
return NewNode;
}
}
void Print (struct Node* head)
{
struct Node* temp = head;
while ( temp != NULL)
{
printf("%d-%d-%d \n", temp->payload.ano, temp->payload.mes,
temp>payload.dia);
fflush(stdout);
temp = temp->next;
}
printf("\n");
}
Node* SortDate (struct Node*);
void SwapNodes (struct Node*, struct Node*);
int main(int argc, char* argv[])
{
CreateCountriesList();
}
Node* CreateCountriesList()
{
char linha[150] = {NULL};
char cabecalho[100] = {NULL};
int i = 0;
dados_temp New_Entry;
dados_temp tail;
int *ptr_head_co;
struct Node* head_countries = NULL;
struct Node* Node = NULL;
FILE *inputf;
inputf = fopen("tempcountries_all.csv", "r");
if (inputf == NULL)
{
printf("Nao da pa abrir o fitchas boi");
exit(EXIT_FAILURE);
}
//gets rid of the first line
fgets(cabecalho, 100, inputf);
for (i = 0; i < 577462 ; i++)
{
fgets(linha, 150, inputf);
//scans the date(amongst other things) from file (yyyy-mm-dd)
sscanf(linha, "%d-%d-%d,%f,%f,%[^,]s", &New_Entry.ano,
&New_Entry.mes,&New_Entry.dia, &New_Entry.temp, &New_Entry.incerteza,
&New_Entry.pais);
if (head_countries == NULL)
{
head_countries = CreateNode(New_Entry);
Node = CreateNode(New_Entry);
}
else
{
head_countries = InsertHead(head_countries, New_Entry);
}
}
fclose(inputf);
head_countries = RemoveNodes(Node);
SortDate(head_countries);
Print(head_countries);
return head_countries;
}
Node* SortDate(struct Node* head)
{
struct Node *i, *j;
for( i = head; i != NULL; i = i->next )
{
if ( i->payload.ano > i->next->payload.ano )
{
SwapNodes(i, i->next);
for (j = i->next; j->payload.ano < j->prev->payload.ano;)
{
SwapNodes(j, j->prev);
}
}
}
}//sort
void SwapNodes(struct Node* node1, struct Node* node2)
{
dados_temp temp = node1->payload;
node1->payload = node2->payload;
node2->payload = temp;
}

Recursive linked list in C

I've just tried to implement a recursive linked list append in C, and for some reason l keeps being NULL no matter what I do, even though I malloc when encountering a NULL value.
The following code prints nothing. Any ideas?
#include <stdlib.h>
#include <stdio.h>
typedef struct node {
unsigned v;
struct node* next;
} node;
void insert(unsigned x, node* l) {
if (l == NULL){
node* new_node = (node*)malloc(sizeof(node));
new_node->v = x;
new_node->next = NULL;
l = new_node;
}
else {
insert(x, l->next);
}
}
void print(node *l) {
if (l == NULL) return;
printf("%d\n", l->v);
print(l->next);
}
int main(){
node* l = NULL;
insert(1, l);
insert(2, l);
print(l);
return 0;
}
Help much appreciated.
EDIT: Even if I initialize it, it's still the same.
#include <stdlib.h>
#include <stdio.h>
typedef struct node {
unsigned v;
struct node* next;
} node;
node* insert(unsigned x, node** ll) {
if (*ll == NULL){
*ll = (node*)malloc(sizeof(node));
(*ll)->v = x;
(*ll)->next = NULL;
}
else {
insert(x, &(*ll)->next);
}
}
void print(node *l) {if (l == NULL) return;
printf("%d\n", l->v);
print(l->next);
}
int main(){
node* l = NULL;
insert(1, &l);
insert(2, &l);
print(l);
return 0;
}
compiled with no gcc no switches
output:
1
2
First off, you're passing l to your function by value so you won't see any changes made to it. Currently, when you set l to new_node, you only change the local value of l in the method insert. You may want to modify your function to return l and set l in your main to the return value of this function.
node *insert(int x, node *l){
//.... your method
return l;
}
In main:
node *l = NULL;
l = insert(1, l);
l = insert(2, l);
Second, your recursive call will not append nodes to your LL for the same reason. Change that call to this:
l->next = insert(x, l);

C linked list to Display contents

Is there any part i have missed in the code?
I am creating a non-empty linked
list and to display the contents of a linked list. Where am I getting it wrong?
#include <stdbool.h>
#include <stdlib.h>
struct node_int
{
void *data;
node next;
};
typedef struct node_int *node;
typedef struct list_int { node first; } *list;
void init_list(list *lp, void *o)
{
*lp = (list) malloc(sizeof(struct list_int));
(*lp)->first = NULL;
(*lp)->first->data = o;
(*lp)->first->next = NULL;
}
void print(list ell, void (*print_data)(void *d))
{
list c;
c = ell;
while (c!NULL)
{
print_data(c->data);
c = ell;
}
}
There are a few problems with your code.
First like to say that I find it bad style to typedef a pointer. If you do that, you should at least use a name which clearly tells that the type is a pointer. Names like list and node make others think of something which is not pointers.
Below is some code showing how it could look without typedef'ed pointers.
#include <stdio.h>
#include <stdlib.h>
struct node_int
{
void *data;
struct node_int* next;
};
typedef struct node_int node;
typedef struct list_int { node* first; } list;
void init_list(list** lp, void *o)
{
// Allocate the list
*lp = malloc(sizeof(list));
if (*lp == NULL) return;
// Allocate the first node
(*lp)->first = malloc(sizeof(node));
if ((*lp)->first == NULL)
{
free(*lp);
*lp = NULL;
return;
}
// Initialize first element
(*lp)->first->data = o;
(*lp)->first->next = NULL;
}
void print(list* ell, void (*print_data)(void *d))
{
if (ell == NULL) return;
node* p = ell->first;
while (p != NULL)
{
print_data(p->data);
p = p->next;
}
}
void myPrint(void* d)
{
int* p = (int*)d;
printf("%d\n", *p);
}
void free_list(list* ell)
{
// Add code here ...
}
int main(void)
{
int a = 1;
list* myList;
init_list(&myList, &a);
if (myList == NULL) return 0;
// Use the list.....
print(myList, myPrint);
free_list(myList);
return 0;
}

error in function that counts the number of times an int appears in a list

I'm trying to count the number of times a given int occurs in a list, but I'm having a difficult time getting my pointers to work. Can someone spot where is my logic failing? Is it because of how I'm implementing the "follows" "->" in the counting function?
//this is in my .h file
typedef struct list_struct LIST;
///// the rest is in my .c file
typedef struct node {
ElemType val;
struct node *next;
} NODE;
struct list_struct {
NODE *front;
NODE *back;
};
//this is my counting function
int lst_count(LIST *l, ElemType x) {
LIST *current = l;
int count = 0;
while (current != NULL) {
if ((current->front->val) == x) count++;
current = current->front->next;
//in the line above I get the following warning:
//"incompatible pointer types assigning to 'LIST*' (aka 'struct list_struct*') from 'struct node*'"
}
return count;
}
Your problem is in the while loop
You are in a list struct, then you do
current->front->next;
Now you are in a NODE type struct, in the next iteration there is no front in NODE.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
struct node *previous;
} NODE;
int lst_count(NODE *l, int x) {
NODE *current = l;
NODE *start = current; /* so that we wont loose the start*/
int count = 0;
while (current != NULL) {
if ((current->val) == x)
count++;
current = current->next;
}
return count;
}
int main()
{
NODE* p = (NODE*)malloc(sizeof(NODE));
NODE* p1 = (NODE*)malloc(sizeof(NODE));
NODE* p2 = (NODE*)malloc(sizeof(NODE));
NODE* start = p;
p->val = 5;
p->next = p1;
p1->next = p2;
p2->next=NULL;
p1->val = 5;
p2->val = 5;
printf("%d", lst_count(start, 5));
}
I got the function to work thanks to your all advises
int lst_count(LIST *l, int x) {
NODE *current = l->front;
int count = 0;
while (current != NULL) {
if ((current->val) == x) count++;
current = current->next;
}
return count;
}

Resources