I want to delete an element from doubly linked list, but i need to using recursion.
I write function but it doesn't work. Can someone tell me where did i a mistake?
int deleteNode(struct dll_node **front, int data){
if((*front) == NULL){
return 0;
}
if(data == (*front)->data){
int tmp = (*front)->data;
(*front)->next = (*front)->prev;
(*front)->prev = (*front)->next;
free(*front);
return tmp;
}
deleteNode((*front)->next, data);
}
there are several problems
you save data in tmp for nothing
you do not update rightly the list
your recursive call does not give right the first argument (must be deleteNode(&(*front)->next, data);, and in fact you must return it), note it is terminal so you can also use a loop
return is missing if the two tests are false
It can be :
int deleteNode(struct dll_node **front, int data){
if((*front) == NULL){
return 0;
}
if(data == (*front)->data){
struct dll_node * d = *front;
if (d->prev == NULL) {
if ((*front = d->next) != NULL)
(*front)->prev = NULL;
}
else if ((d->prev->next = d->next) != NULL)
d->next->prev = d->prev;
free(d);
return data;
}
return deleteNode(&(*front)->next, data);
}
Full code to check :
#include <stdio.h>
#include <stdlib.h>
struct dll_node {
int data;
struct dll_node * prev;
struct dll_node * next;
};
int deleteNode(struct dll_node **front, int data){
if((*front) == NULL){
return 0;
}
if(data == (*front)->data){
struct dll_node * d = *front;
if (d->prev == NULL) {
if ((*front = d->next) != NULL)
(*front)->prev = NULL;
}
else if ((d->prev->next = d->next) != NULL)
d->next->prev = d->prev;
free(d);
return data;
}
return deleteNode(&(*front)->next, data);
}
struct dll_node * mk(int d)
{
struct dll_node * r = malloc(sizeof(struct dll_node));
r->data = d;
r->prev = NULL;
r->next = NULL;
return r;
}
void pr(struct dll_node * l)
{
while (l != NULL) {
printf("%d", l->data);
if (l->prev)
printf(" prev:%d\n", l->prev->data);
else
putchar('\n');
l = l->next;
}
}
int main()
{
struct dll_node * head = mk(1);
struct dll_node * a = mk(2);
struct dll_node * b = mk(3);
head->next = a;
a->prev = head;
b->prev = a;
a->next = b;
pr(head);
puts("\ndel 3");
deleteNode(&head, 3);
pr(head);
puts("\ndel 1");
deleteNode(&head, 1);
pr(head);
puts("\ndel 2");
deleteNode(&head, 2);
pr(head);
}
Compilation and executions :
pi#raspberrypi:/tmp $ gcc -Wall l.c
pi#raspberrypi:/tmp $ ./a.out
1
2 prev:1
3 prev:2
del 3
1
2 prev:1
del 1
2
del 2
pi#raspberrypi:/tmp $ valgrind ./a.out
==8496== Memcheck, a memory error detector
==8496== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8496== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==8496== Command: ./a.out
==8496==
1
2 prev:1
3 prev:2
del 3
1
2 prev:1
del 1
2
del 2
==8496==
==8496== HEAP SUMMARY:
==8496== in use at exit: 0 bytes in 0 blocks
==8496== total heap usage: 4 allocs, 4 frees, 1,060 bytes allocated
==8496==
==8496== All heap blocks were freed -- no leaks are possible
==8496==
==8496== For lists of detected and suppressed errors, rerun with: -s
==8496== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi#raspberrypi:/tmp $
Related
I want to find an algorithm to keep only one occurrence of each number in a linked list using recursion
,I know recursion is not at all a good choice to solve this problem ,but I want to try it.
for more calirification:
input : 1->2->1->3->3->2->1->4
output : 1->2->3->4
Here is the program that i've made to keep only one occurrence of a given number using recursion, but i couldn't develop it in order to solve the whole problem. can I get some help? thanks in advance.
list* wipe(list* head,int val)
{
if(head==NULL) return head;
static int occ=1;
if(head->data == val)
{
if(occ-- < 1)
{
list* temp=head;
head=head->next;
free(temp);
return wipe(head,val);
}
}
head->next=wipe(head->next,val);
return head;
}
occ is set to 1 only the very time you execute the function, so from the second time (head->data == val) is true whatever val the test (occ-- < 1) will be true, this is not the right way.
You can do something like that where the list is modified to only contain unique numbers :
#include <stdio.h>
#include <stdlib.h>
typedef struct List {
struct List * next;
int data;
} List;
/* remove from l all the cells having data equals to v */
List * wipe(int v, List * l)
{
if (l == NULL)
return l;
else if (l->data != v) {
l->next = wipe(v, l->next);
return l;
}
else {
List * n = l->next;
free(l);
return wipe(v, n);
}
}
/* modify the argument to not have duplicated numbers */
void simplify(List * l)
{
while (l != NULL) {
l->next = wipe(l->data, l->next);
l = l->next;
}
}
/* helper function to construct a list */
List * mk(int v, List * n) {
List * l = malloc(sizeof(*l));
l->data = v;
l->next = n;
return l;
}
/* print the list */
void pr(List * l)
{
while (l != NULL) {
printf("%d ", l->data);
l = l->next;
}
putchar('\n');
}
int main()
{
List * l = mk(1, mk(2, mk(1, mk(3, mk(3, mk(2, mk(1, mk(4, NULL))))))));
pr(l);
simplify(l);
pr(l);
/* free the rest of the list */
while (l) {
List * n = l->next;
free(l);
l = n;
}
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -Wall c.c
pi#raspberrypi:/tmp $ ./a.out
1 2 1 3 3 2 1 4
1 2 3 4
pi#raspberrypi:/tmp $ valgrind ./a.out
==3988== Memcheck, a memory error detector
==3988== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3988== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3988== Command: ./a.out
==3988==
1 2 1 3 3 2 1 4
1 2 3 4
==3988==
==3988== HEAP SUMMARY:
==3988== in use at exit: 0 bytes in 0 blocks
==3988== total heap usage: 9 allocs, 9 frees, 1,088 bytes allocated
==3988==
==3988== All heap blocks were freed -- no leaks are possible
==3988==
==3988== For lists of detected and suppressed errors, rerun with: -s
==3988== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi#raspberrypi:/tmp $
That way have the complexity O(n2)
A faster way is to first sort the elements in the list then remove the duplicates, allowing to have the complexity of the sort so possibly O(n*log(n)) (probably using a temporary array to sort)
If I have understood correctly you need a recursive function that appends a number to a list only in case when the number is not present already in the list.
If so then the recursive function can look for example like
int append( list **head, int val )
{
if ( *head == NULL )
{
*head = malloc( sizeof( **head ) );
int success = *head != NULL;
if ( success )
{
( *head )->data = val;
( *head )->next = NULL;
}
return success;
}
else if ( ( *head )->data != val )
{
return append( &( *head )->next, val );
}
else
{
return 0;
}
}
And if in main you have a declaration like this
list *head = NULL;
then the function can be called for example like
append( &head, val );
Or like
if ( append( &head, val ) )
{
printf( "The value %d is appended to the list.\n", val );
}
I am studying the lists and I came across this exercise which asks me to do the following steps:
Define a function that, given two lists of integers L1 and L2, and an integer n>0, eliminate from the first list the nodes for which the sum of the contents of L1 and L2 in the corresponding position (with respect to the original positions) is a multiple of n. If L2 ends, consider only the content of L1 instead of the sum.
I tried to analyze the problem with a single list and in this case I had no problems, but in this specific case I couldn't figure out how to proceed.
my problem is that I can't understand how properly build the various cases (L1 must be always != NULL, so I have: L1 != NULL && L2 != NULL or L1 != NULL && L2 == NULL).
Can someone explain to me the procedure to be performed and where am I wrong?
This is my attempt:
struct data
{
int d;
struct data *next;
};
typedef struct data Nodo;
typedef Nodo *LIST;
void function(LIST *l1, LIST l2, int n)
{
LIST p, head_1, head_2;
while((*l1 != NULL && l2 != NULL)&&((*l1)->d + l2->d) % n == 0)
{
p = *l1;
*l1 = (*l1)->next;
free(p);
}
while((*l1 != NULL) && ((*l1)->d + l2->d) % n == 0)
{
p = *l1;
*l1 = (*l1)->next;
free(p);
}
if (*l1 != NULL)
{
head_1 = *l1;
head_2 = l2;
while(head_1->next != NULL)
{
if (((head_1->next->d + head_2->next->d) % n) == 0)
{
p = head_1->next;
head_1->next = head_1->next->next;
free(p);
}
else
{
head_1 = head_1->next;
head_2 = head_2->next;
}
}
}
}
Example:
L1: 4->4->11->3->4->8->7->NULL
L2: 5->1->5->1->5
OUTPUT(L1): 4->4->4->7->NULL
You have a problem of logic with the consecutive loops :
while((*l1 != NULL && l2 != NULL)&&((*l1)->d + l2->d) % n == 0) {
...
}
while((*l1 != NULL) && ((*l1)->d + l2->d) % n == 0){
...
}
if the sum of the elements are not a multiple of n you need to move to the next element, but you do not do
Out of that to hide a pointer with a typedef like you do with typedef Nodo *LIST; is dangerous and is a good way to introduce problem, I recommend you to never do that.
You can do that :
void removeIf(Nodo ** l1, Nodo * l2, int n)
{
while ((*l1 != NULL) && (l2 != NULL)) {
if ((((*l1)->d + l2->d) % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
l2 = l2->next;
}
// case where l2 is shorter than l1
while (*l1 != NULL) {
if (((*l1)->d % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
}
}
Making a full program for
L1: 4->4->11->3->4->8->7
L2: 5->1->5->1->5
N : 2
#include <stdio.h>
#include <stdlib.h>
struct data {
int d;
struct data *next;
};
typedef struct data Nodo;
void removeIf(Nodo ** l1, Nodo * l2, int n)
{
while ((*l1 != NULL) && (l2 != NULL)) {
if ((((*l1)->d + l2->d) % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
l2 = l2->next;
}
// case where l2 is shorter than l1
while (*l1 != NULL) {
if (((*l1)->d % n) == 0) {
/* cell must be removed */
Nodo * rm = *l1;
*l1 = (*l1)->next;
free(rm);
}
else {
/* cell not removed */
l1 = &(*l1)->next;
}
}
}
Nodo * make(int v, Nodo * n)
{
Nodo * r = malloc(sizeof(Nodo));
r->d = v;
r->next = n;
return r;
}
void del(Nodo ** pl)
{
while (*pl != NULL) {
Nodo * n = *pl;
*pl = (*pl)->next;
free(n);
}
}
int main()
{
Nodo * l1 = make(4, make(4, make(11, make(3, make(4, make(8, make(7, NULL)))))));
Nodo * l2 = make(5, make(1, make(5, make(1, make(5, NULL)))));
removeIf(&l1, l2, 2);
/* show result */
for (Nodo * l = l1; l != NULL; l = l->next)
printf("%d ", l->d);
putchar('\n');
/* free resources */
del(&l1);
del(&l2);
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra ll.c
pi#raspberrypi:/tmp $ ./a.out
4 4 4 7
pi#raspberrypi:/tmp $
Execution under valgrind :
pi#raspberrypi:/tmp $ valgrind ./a.out
==3758== Memcheck, a memory error detector
==3758== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3758== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3758== Command: ./a.out
==3758==
4 4 4 7
==3758==
==3758== HEAP SUMMARY:
==3758== in use at exit: 0 bytes in 0 blocks
==3758== total heap usage: 13 allocs, 13 frees, 1,120 bytes allocated
==3758==
==3758== All heap blocks were freed -- no leaks are possible
==3758==
==3758== For counts of detected and suppressed errors, rerun with: -v
==3758== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi#raspberrypi:/tmp $
I can't seem to find the problem to why there is always a leak with the prio_q_create function. I do free it with prio_q_destroy but valgrind still shows a leak error.
#include <stdlib.h>
#include <stdio.h>
typedef struct prio_q prio_q;
typedef struct elem elem;
struct prio_q {
int size;
struct elem *first;
};
struct elem {
void *data;
int prio;
struct elem *next;
};
struct prio_q *prio_q_create() {
prio_q *list = calloc(1, sizeof(prio_q));
list->first = NULL;
list->size = 0;
return list;
}
void prio_q_push(struct prio_q *q, void *data, int prio) {
elem *e = calloc(1, sizeof(elem));
e->prio = prio;
e->data = data;
e->next = NULL;
if (q->first == NULL) {
q->first = e;
q->size = q->size + 1;
} else {
if (q->first->prio < prio) {
e->next = q->first;
q->first = e;
q->size = q->size + 1;
} else {
elem *temp = q->first;
while (temp->next != NULL && temp->next->prio >= prio) {
temp = temp->next;
}
e->next = temp->next;
temp->next = e;
q->size = q->size + 1;
}
}
}
void *prio_q_pop(struct prio_q *q) {
if (q->first != NULL) {
elem *temp = q->first;
q->first = q->first->next;
void *data = temp->data;
temp->next = NULL;
free(temp);
return data;
} else
exit(0);
}
void *prio_q_front(struct prio_q *q) {
return q->first->data;
}
void prio_q_destroy(struct prio_q *q) {
elem *temp = q->first;
elem *next_temp;
while (temp != NULL) {
next_temp = temp->next;
free(temp);
temp = next_temp;
}
free(q);
}
int main() {
struct prio_q *queue;
char *s;
int i;
queue = prio_q_create();
prio_q_push(queue, "amet...", 2);
prio_q_push(queue, "ipsum", 7);
prio_q_push(queue, "dolor", 4);
prio_q_push(queue, "Lorem", 22);
prio_q_push(queue, "sit", 3);
prio_q_push(queue, "Hello World", 1);
prio_q_push(queue, "Bye World", 0);
for (i = 0; i < 5; i++) {
s = prio_q_pop(queue);
printf("%s\n", s);
}
s = prio_q_front(queue);
printf("%s\n", s);
prio_q_destroy(queue);
return 0;
}
Should be the whole code. The main mostly pushes some strings with prio number onto the list and prints them out via a loop.
There is no leak in the posted code. Either you are testing code that is not posted or your version of Valgrind might detect a false positive caused by the C library allocating a buffer for stdout. Try without the printf statements.
Here is my Valgrind trace:
chqrlie$ make memleak
gcc -O2 -funsigned-char -std=c99 -Wall -Wextra -W -Wmissing-field-initializers -lm -o memleak memleak.c
chqrlie$ valgrind ./memleak
==45671== Memcheck, a memory error detector
==45671== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==45671== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==45671== Command: ./memleak
==45671==
amet...
ipsum
dolor
Lorem
sit
Hello World
==45671==
==45671== HEAP SUMMARY:
==45671== in use at exit: 0 bytes in 0 blocks
==45671== total heap usage: 8 allocs, 8 frees, 184 bytes allocated
==45671==
==45671== All heap blocks were freed -- no leaks are possible
==45671==
==45671== For counts of detected and suppressed errors, rerun with: -v
==45671== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
chqrlie$
I am trying to create a linked list with elements I have, but I need 24 nodes for this and I don't want to end up like this:
head->next->next->next->next->next->next->next->id = 1;
How can I prevent this?
I tried creating something likes but all nodes(obviously) are pointing the same data.
void init_board(block **head)
{
block temp;
temp.id=0;
temp.name="Start";
temp.price=0;
temp.rent=0;
temp.next = NULL;
*head = &temp;
(*head)->next = NULL;
(*head)->next = (block*) malloc(sizeof(block*));
temp = head->next;
temp.id=1;
temp.name="End";
temp.price=16000;
temp.rent=800;
temp.next = NULL;
}
I am trying to create a linked list with elements I have, but I need 24 nodes for this and I don't want to end up like this:
head->next->next->next->next->next->next->next->id = 1;
How can I prevent this?
updating head (not only *head)
block temp;
...
temp = head->next;
you cannot do that, because temp is s struct but next a pointer
I tried creating something likes but all nodes(obviously) are pointing the same data.
you need to allocate a new cell for all the new element, including for the first you currently put in the stack (never return the address of something saved in the stack)
(head)->next = (block) malloc(sizeof(block*));
this is not what you want, you need to alloc for a block, not for a block *
Example initializing with two cells :
void init_board(block **plast)
{
*plast = malloc(sizeof(block));
(*plast)->id=0;
(*plast)->name="Start";
(*plast)->price=0;
(*plast)->rent=0;
(*plast)->next = malloc(sizeof(block));
plast = &(*plast)->next;
(*plast)->id=1;
(*plast)->name="End";
(*plast)->price=16000;
(*plast)->rent=800;
(*plast)->next = NULL;
}
int main()
{
block * l;
init_board(&l);
}
Of course if you have 20 block to initialize to expanse each case is not practical, may be the values come from a file or an array like that :
#include <stdio.h>
#include <stdlib.h>
typedef struct block {
int id;
const char * name;
int price;
int rent;
struct block * next;
} block;
const block Boards[] = {
{ 0, "Start", 0, 0, NULL },
{ 2, "Intermediate", 123, 456, NULL },
{ 1, "End", 16000, 800, NULL }
};
void init_board(block **plast)
{
for (const block * b = Boards; b != Boards + sizeof(Boards)/sizeof(Boards[0]); ++b) {
*plast = malloc(sizeof(block));
(*plast)->id = b->id;
(*plast)->name = b->name;
(*plast)->price = b->price;
(*plast)->rent = b->rent;
(*plast)->next = NULL;
plast = &(*plast)->next;
}
}
int main()
{
block * blocks;
init_board(&blocks);
/* debug */
for (block * b = blocks; b != NULL; b = b->next)
printf("%d %s %d %d\n", b->id, b->name, b->price, b->rent);
/* free resources */
while (blocks != NULL) {
block * b = blocks;
blocks = blocks->next;
free(b);
}
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall l.c
pi#raspberrypi:/tmp $ ./a.out
0 Start 0 0
2 Intermediate 123 456
1 End 16000 800
Execution under valgrind :
pi#raspberrypi:/tmp $ valgrind ./a.out
==6819== Memcheck, a memory error detector
==6819== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6819== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6819== Command: ./a.out
==6819==
0 Start 0 0
2 Intermediate 123 456
1 End 16000 800
==6819==
==6819== HEAP SUMMARY:
==6819== in use at exit: 0 bytes in 0 blocks
==6819== total heap usage: 4 allocs, 4 frees, 1,084 bytes allocated
==6819==
==6819== All heap blocks were freed -- no leaks are possible
==6819==
==6819== For counts of detected and suppressed errors, rerun with: -v
==6819== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
pi#raspberrypi:/tmp $
struct link
{
int data;
int dataOne;
// data n....
struct link* link;
};
// HeadNode
struct link* pHeadLink = NULL;
//add the link and return the current.
struct link* appendLink()
{
if(pHeadLink == NULL)
{
pHeadLink = (struct link*) malloc(sizeof(struct link));
pHeadLink->link = NULL;
return pHeadLink;
}
struct link *pTempLink = pHeadLink;
while(pTempLink->link != NULL)
{
pTempLink = pTempLink->link;
}
pTempLink->link = (struct link*) malloc(sizeof(struct link));
pTempLink->link->link = NULL;
return pTempLink;
}
// calling function:
int fun()
{
loop() // loop for 24 times.
{
struct link* pFillDataLink = appendLink();
// here you can fill rest the items like below.
pFillDataLink->data = 34;
pFillDataLink->dataOne = 334;
// etc....
}
}
I have define a type struct like that:
typedef struct _liste {
int val;
struct _liste *suiv;
} Liste;
But when I want to save valuer into type but it not work
my code:
Liste A;
for (int i = 0; i<3; i++){
scanf("%d",&A.val);
*A = A.suiv
}
but variable A is not saved.
How to fix? Thanks
In
typedef struct _liste {
int val;
struct _liste *suiv;
} Liste;
Liste A;
for (int i = 0; i<3; i++){
scanf("%d",&A.val);
*A = A.suiv
}
there are 2 problems
*A = A.suiv is invalid and you wanted A = *(A.suiv) to respect the types (out of any behavior)
A.suiv is not initialized, you miss an allocation for each new cell
A valid code can be :
Liste * head;
Liste ** p = &head;
for (int i = 0; i != 3; i++) {
*p = malloc(sizeof(Liste));
scanf("%d",&(*p)->val);
p = &(*p)->suiv;
}
*p = NULL;
A full example :
#include <stdio.h>
#include <stdlib.h>
typedef struct _liste {
int val;
struct _liste *suiv;
} Liste;
int main()
{
Liste * head;
Liste ** p = &head;
for (int i = 0; i != 3; i++) {
*p = malloc(sizeof(Liste));
printf("valeur: ");
scanf("%d",&(*p)->val); /* better to check scanf return 1 */
p = &(*p)->suiv;
}
*p = NULL;
/* show result and free ressources */
printf("la liste est :");
while (head != NULL) {
printf(" %d", head->val);
Liste * l = head;
head = head->suiv;
free(l);
}
putchar('\n');
}
Compilation and execution :
/tmp % gcc -pedantic -Wall -Wextra l.c
/tmp % ./a.out
valeur: 1
valeur: 2
valeur: 3
la liste est : 1 2 3
execution under valgrind
/tmp % valgrind ./a.out
==32505== Memcheck, a memory error detector
==32505== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==32505== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==32505== Command: ./a.out
==32505==
valeur: 1
valeur: 2
valeur: 3
la liste est : 1 2 3
==32505==
==32505== HEAP SUMMARY:
==32505== in use at exit: 0 bytes in 0 blocks
==32505== total heap usage: 3 allocs, 3 frees, 48 bytes allocated
==32505==
==32505== All heap blocks were freed -- no leaks are possible
==32505==
==32505== For counts of detected and suppressed errors, rerun with: -v
==32505== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
If you do not want to have the list in the heap :
#include <stdio.h>
typedef struct _liste {
int val;
struct _liste *suiv;
} Liste;
#define N 3
int main()
{
Liste liste[N];
for (int i = 0; i != N; i++) {
printf("valeur: ");
scanf("%d", &liste[i].val); /* better to check scanf return 1 */
liste[i].suiv = &liste[i + 1];
}
liste[N-1].suiv = NULL;
/* show result (as a list, forget in an array) */
Liste * p = liste;
printf("la liste est :");
while (p != NULL) {
printf(" %d", p->val);
p = p->suiv;
}
putchar('\n');
}
but in that case better to not use a list but just an array of int ;-)