Given linked list pairs swap by changing links - c

I have a singly linked list where I get the struct Node* head, and the return value is void. I'd like to swap in pairs without copying the data.
For example, if the input is 2->4->6 then the output is 4->2->6. But if the input is 2->4->6->7 then the output is 4->2->7->6.
Here is my code but it doesn't work.
void swapPairs(struct Node *head) {
struct Node *node;
while (head && head->next) {
struct Node *nxt = head->next;
head->next = nxt->next;
nxt->next = head;
node->next = nxt;
node = head;
head = node->next;
}
}

You need to pass the pointer to the head (or current) node by reference. Otherwise the function will deal with a copy of the value of the passed pointer. Changing the copy does not influence on the original pointer.
Here is a demonstrative program that shows how a function that swaps adjacent nodes can be written.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Node
{
int data;
struct Node *next;
};
struct Node *insert( struct Node *head, size_t pos, int data )
{
if (head == NULL || pos == 0)
{
struct Node *new_node = ( struct Node * )malloc( sizeof( struct Node ) );
new_node->next = head;
new_node->data = data;
head = new_node;
}
else
{
head->next = insert( head->next, pos - 1, data );
}
return head;
}
FILE * display( const struct Node *head, FILE *fp )
{
for ( ; head != NULL; head = head->next )
{
fprintf( fp, "%d -> ", head->data );
}
fputs( "null\n", fp );
return fp;
}
void swap( struct Node **current )
{
/*
| A | -> | A | B | -> | B | C |
head
Step 1:
| B | | A | C | | B | C |
head
Step 2:
| B | | A | C | | B | A |
head
*/
// Step 1:
struct Node *tmp = *current;
*current = ( *current )->next;
tmp->next = ( *current )->next;
// Step 2:
( *current )->next = tmp;
}
void swapPairs( struct Node **head )
{
for ( ; *head && ( *head )->next; head = &( *head )->next->next)
{
swap( head );
}
}
int main()
{
struct Node *head = NULL;
const int N = 10;
srand( ( unsigned int )time( NULL ) );
for ( int i = 0; i < N; i++ )
{
head = insert( head, rand() %( i + 1 ), rand() % N );
}
fputc( '\n', display( head, stdout ) );
swapPairs( &head );
fputc( '\n', display( head, stdout ) );
}
The program output might look like
4 -> 7 -> 8 -> 1 -> 4 -> 8 -> 9 -> 0 -> 4 -> 6 -> null
7 -> 4 -> 1 -> 8 -> 8 -> 4 -> 0 -> 9 -> 6 -> 4 -> null

Related

C, How to Remove Element From Queue?

Update: we believe to find some bugs in both solutions , you are invited to share your ideas too :)
I was trying to implement my own data structure which combines list with queue in C.
my data structure has 2 pointers, front which points to the oldest member in the queue and rear which points to the newly added member which each member points to the one which got inserted after it.
For example if I insert 1 then 2 then 3, I will have:
NULL <-3 <- 2 <- 1 // 1 is front and 3 is rear.
Now I wanted to support removing element from this DS so I starting imeplemnting it and descovvered tens of edge cases like:
if the member is the front then change the front for DS and free the member, BUT if the front is null now then change rear to null too or the other code won't work as expected.
if the member is in middle release it then go back to prev member and update its next But this seems really hard
nearly the same for the rear member except we need to update rear now and only change the pointer to the element to its right (NULL is to its left)
How am I supposed to do something like this?
I already had tens of ideas and implementation for days but simply all failed or I did something really bad making the run time complexity much higher or I wrote 170 lines which had contradictions and left unfinished conditions (by using 2 pointers).
Any help please implementing this?
struct queue_node
{
int key;
struct queue_node *next;
};
struct queue
{
int queue_size;
struct queue_node *front, *rear;
};
int requeue(struct queue *q, int val)
{
struct queue_node *tmp = q->front;
while (tmp!=NULL)
{
if (tmp->key==val)
{
if (tmp==q->front)
{
q->front=tmp->next;
if (q->front == NULL)
{
q->rear = NULL;
}
free(tmp);
}else if (tmp == q->rear)
{
}
return 0; // found
}
tmp=tmp->next;
}
return -1; // not found
}
typedef struct queue_node
{
int key;
struct queue_node *next;
}node;
typedef struct
{
size_t size;
node *head;
node *tail;
}queue;
node *append(queue *q, int key)
{
node *n = malloc(sizeof(*n));
node *c = q -> head;
if(n)
{
if(!q -> head) q -> head = n;
else
{
while(c -> next) c = c -> next;
c -> next = n;
}
n -> key = key;
n -> next = NULL;
q -> size++;
q -> tail = n;
}
return n;
}
int removenode(queue *q, int key)
{
node *n = q -> head, *p = q -> head;
int result = 0;
while(n)
{
if(n -> key == key)
{
if(n == p)
{
q -> head = n -> next;
if(!n -> next) q -> tail = n;
}
else
{
p -> next = n -> next;
if(!p -> next) q -> tail = p;
}
free(n);
q -> size--;
result = 1;
break;
}
if(p != n) p = p -> next;
n = n -> next;
}
return result;
}
void printqueue(queue *q)
{
node *n = q -> head;
printf("The queue:\n");
while(n)
{
printf("Node key = %d\n", n -> key);
n = n -> next;
}
printf("--------------\n");
if(q -> head) printf("Head key: %d, Tail key: %d, Queue size: %zu\n -------------\n\n", q -> head -> key, q -> tail -> key, q -> size);
else printf("Queue empty\n------------\n\n");
}
int main(void)
{
queue q = {0,};
append(&q,1);
append(&q,2);
append(&q,3);
append(&q,4);
printqueue(&q);
removenode(&q,3);
printqueue(&q);
removenode(&q,1);
printqueue(&q);
removenode(&q,4);
printqueue(&q);
removenode(&q,2);
printqueue(&q);
}
Result:
The queue:
Node key = 1
Node key = 2
Node key = 3
Node key = 4
--------------
Head key: 1, Tail key: 4, Queue size: 4
-------------
The queue:
Node key = 1
Node key = 2
Node key = 4
--------------
Head key: 1, Tail key: 4, Queue size: 3
-------------
The queue:
Node key = 2
Node key = 4
--------------
Head key: 2, Tail key: 4, Queue size: 2
-------------
The queue:
Node key = 2
--------------
Head key: 2, Tail key: 2, Queue size: 1
-------------
The queue:
--------------
Queue empty
------------
Program demo
The function can be defined the following way
int requeue( struct queue *q, int val )
{
struct queue_node **current = &q->front;
struct queue_node *prev = NULL;
while ( *current && ( *current )->key != val )
{
prev = *current;
current = &( *current )->next;
}
int success = *current == NULL ? -1 : 0;
if ( success == 0 )
{
struct queue_node *tmp = *current;
*current = ( *current )->next;
free( tmp );
--q->queue_size;
if ( *current == NULL ) q->rear = prev;
}
return success;
}
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
struct queue_node
{
int key;
struct queue_node *next;
};
struct queue
{
int queue_size;
struct queue_node *front, *rear;
};
int requeue( struct queue *q, int val )
{
struct queue_node **current = &q->front;
struct queue_node *prev = NULL;
while ( *current && ( *current )->key != val )
{
prev = *current;
current = &( *current )->next;
}
int success = *current == NULL ? -1 : 0;
if ( success == 0 )
{
struct queue_node *tmp = *current;
*current = ( *current )->next;
free( tmp );
--q->queue_size;
if ( *current == NULL ) q->rear = prev;
}
return success;
}
int push( struct queue *q, int key )
{
struct queue_node *node = malloc( sizeof( struct queue_node ) );
int success = node != NULL;
if ( success )
{
node->key = key;
node->next = NULL;
if ( q->rear == NULL )
{
q->front = q->rear = node;
}
else
{
q->rear = q->rear->next = node;
}
++q->queue_size;
}
return success;
}
void display( const struct queue *q )
{
for ( struct queue_node *current = q->front; current; current = current->next )
{
printf( "%d -> ", current->key );
}
puts( "null" );
}
int main(void)
{
struct queue q = { .front = NULL, .rear = NULL };
push( &q, 1 );
push( &q, 2 );
push( &q, 3 );
push( &q, 4 );
display( &q );
requeue( &q, 4 );
display( &q );
push( &q, 4 );
display( &q );
requeue( &q, 1 );
display( &q );
requeue( &q, 3 );
display( &q );
requeue( &q, 4 );
display( &q );
requeue( &q, 2 );
display( &q );
push( &q, 1 );
push( &q, 2 );
push( &q, 3 );
push( &q, 4 );
display( &q );
return 0;
}
The program output is
1 -> 2 -> 3 -> 4 -> null
1 -> 2 -> 3 -> null
1 -> 2 -> 3 -> 4 -> null
2 -> 3 -> 4 -> null
2 -> 4 -> null
2 -> null
null
1 -> 2 -> 3 -> 4 -> null
If for testing to add a call of the function printf to this code snippet within the function requeue
if ( success == 0 )
{
struct queue_node *tmp = *current;
*current = ( *current )->next;
printf( "tmp->key == %d, tmp == %p\n", tmp->key, ( void * )tmp );
free( tmp );
--q->queue_size;
if ( *current == NULL ) q->rear = prev;
}
Then the output of the demonstrative program can look like
1 -> 2 -> 3 -> 4 -> null
tmp->key == 4, tmp == 0x55b55f9e02c0
1 -> 2 -> 3 -> null
1 -> 2 -> 3 -> 4 -> null
tmp->key == 1, tmp == 0x55b55f9e0260
2 -> 3 -> 4 -> null
tmp->key == 3, tmp == 0x55b55f9e02a0
2 -> 4 -> null
tmp->key == 4, tmp == 0x55b55f9e02c0
2 -> null
tmp->key == 2, tmp == 0x55b55f9e0280
null
1 -> 2 -> 3 -> 4 -> null

How can I de-concatenate a Linked List into 3 separate Link Lists in C?

so I'm pretty new to Data Structures and I'm just getting introduced to Singly Linked List. The task I have right now, is to:
Concatenate 3x Linked Lists into a single Linked List
De-Concatenate the large Linked List back to 3x Linked Lists.
I have managed to do the first step, I create 3 separate Linked Lists and then append them with eachother. But I'm running into a small problem at the De-Concatenation stage and I'm hoping someone can explain what I'm doing wrong. First and foremost, here's my code...
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node * next;
} node;
node * createLL(int);
void displayLL(node * head);
node * concatenate(node * head1, node * head2, node * head3);
void deconcatenate(node * head1, node * head2, node * head3);
int main() {
struct node * head1 = NULL;
struct node * head2 = NULL;
struct node * head3 = NULL;
printf("Creating #1 Link List.. \n");
head1 = createLL(5);
displayLL(head1);
printf("\nCreating #2 Link List .. \n");
head2 = createLL(5);
displayLL(head2);
printf("\nCreating #3 Link List .. \n");
head3 = createLL(5);
displayLL(head3);
printf("\nConcatenating the Three Link Lists");
head1 = concatenate(head1,head2,head3);
displayLL(head1);
printf("\nDe-Concatenating the Link List into 3 Link Lists");
deconcatenate(head1,head2,head3);
printf("\nList #1\n");
displayLL(head1);
printf("\nList #2\n");
displayLL(head2);
printf("\nList #3\n");
displayLL(head3);
}
void deconcatenate(node * head1, node * head2, node * head3) {
struct node * temp1;
struct node * temp2;
struct node * temp3;
int i,j,k;
i = j = k = 0;
temp1 = head1;
while (i < 5) {
temp1 = temp1->next;
i++;
}
head2 = temp1; // 6
temp1 = NULL;
temp2 = head2;
while (j < 5) {
temp2 = temp2->next;
j++;
}
head3 = temp2;
temp2 = NULL;
temp3 = head3;
while (k < 5) {
temp3 = temp3->next;
k++;
}
temp3 = NULL;
}
void displayLL(node * HEAD) {
for(node * p = HEAD; p != NULL; p = p->next) {
printf("%d->",p->data);
}
printf("\n");
}
node * concatenate(node * head1, node * head2, node * head3) {
struct node * temp = head1;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = head2;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = head3;
return head1;
}
node * createLL(int n) {
int i = 0;
struct node * head = NULL;
struct node * temp = NULL;
struct node * p = NULL;
for(i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
printf("Enter data in Node #%d",i);
scanf("%d",&(temp->data));
temp->next = NULL;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
And here's the output
As you can see, after De-Concatenation, LinkList #1 only has "1" node while it should have nodes of value 1 to 5. LinkList #2 has way too many nodes than it should have. It should have nodes of value 6 to 10 but it has nodes from 6 to 15. Link List #3 is the only one with accurate value of nodes.
So what am I doing wrong in the deconcatenate Function?
The while loops inside your void deconcatenate(), shouldn't their conditions be less than other than equal to? And beside you don't need to loop through the last list just to set the last element's next pointer to NULL because you already did that when you created the very first linked list.
In my opinion the assignment is too difficult for a beginner.
If you are going to build a list from other three lists by concatenating their nodes then pointers to head nodes of the three lists shall be passed by reference because the lists will being changed within the function concatenate.
That is after calling the function the three lists shall be empty.
In C passing an object by reference to a function means passing the object indirectly through a pointer to it. In this case the function will have a direct access to the object by dereferencing the pointer that points to the object.
So the function should be declared at least like
node * concatenate(node ** head1, node ** head2, node ** head3);
The same considerations are aplayed to the function deconcatenate. After calling the function the original list shall be empty because its elements are being moved to three other lists.
That is the function should be declared at least like
void deconcatenate(node **source_head, node ** head1, node ** head2, node ** head3);
However these functions have too many parameters. As the both functions deal with a triple of pointers to head nodes it will be better to declare a structure that has three data members that keep pointers to pointers to head nodes and to use an object of this structure as a functions' parameter.
For example
typedef struct triple_lists
{
node **head1;
node **head2;
node **head3;
} triple_lists;
and
node * concatenate( triple_lists triple );
void deconcatenate( node **head, triple_lists triple );
As I have understood correctly the function deconcatenate shall split a source list into three other lists such a way that each list will contain adjacent elements of the source list and also the source list shall be divided into three more or less equal parts.
If so then approach can be the following. You need three pointers to nodes that will specify ends of each of the three lists. When the first pointer is advanced one time, the second pointer will be advanced two times and the third pointer will be advanced three times until the source node will not be exhausted.
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
} node;
typedef struct triple_lists
{
node **head1;
node **head2;
node **head3;
} triple_lists;
int append( node **head, int data )
{
node *new_node = malloc( sizeof( *new_node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = NULL;
while ( *head ) head = &( *head )->next;
*head = new_node;
}
return success;
}
FILE * display( const node *head, FILE *fp )
{
for ( ; head != NULL; head = head->next )
{
fprintf( fp, "%d -> ", head->data );
}
fputs( "null", fp );
return fp;
}
node * concatenate( triple_lists triple )
{
node *head = NULL;
node **current = &head;
*current = *triple.head1;
*triple.head1 = NULL;
while ( *current != NULL ) current = &( *current )->next;
*current = *triple.head2;
*triple.head2 = NULL;
while ( *current != NULL ) current = &( *current )->next;
*current = *triple.head3;
*triple.head3 = NULL;
return head;
}
void deconcatenate( node **head, triple_lists triple )
{
*triple.head1 = *head;
*triple.head2 = *head;
*triple.head3 = *head;
triple_lists tails = { head, head, head };
while ( *tails.head3 != NULL )
{
for ( size_t i = 0; *tails.head1 != NULL && i < 1; i++ )
{
tails.head1 = &( *tails.head1 )->next;
}
for ( size_t i = 0; *tails.head2 != NULL && i < 2; i++ )
{
tails.head2 = &( *tails.head2 )->next;
}
for ( size_t i = 0; *tails.head3 != NULL && i < 3; i++ )
{
tails.head3 = &( *tails.head3 )->next;
}
}
*head = NULL;
*triple.head2 = *tails.head1;
*tails.head1 = NULL;
*triple.head3 = *tails.head2;
*tails.head2 = NULL;
}
int main(void)
{
node *head1 = NULL;
node *head2 = NULL;
node *head3 = NULL;
int i = 0;
while ( i < 10 )
{
append( &head1, i++ );
}
while ( i < 15 )
{
append( &head2, i++ );
}
while ( i < 18 )
{
append( &head3, i++ );
}
printf( "list1: " );
putc( '\n', display( head1, stdout ) );
printf( "list2: " );
putc( '\n', display( head2, stdout ) );
printf( "list3: " );
putc( '\n', display( head3, stdout ) );
putchar( '\n' );
triple_lists triple = { &head1, &head2, &head3 };
node *head0 = concatenate( triple );
printf( "list0: " );
putc( '\n', display( head0, stdout ) );
printf( "list1: " );
putc( '\n', display( head1, stdout ) );
printf( "list2: " );
putc( '\n', display( head2, stdout ) );
printf( "list3: " );
putc( '\n', display( head3, stdout ) );
putchar( '\n' );
deconcatenate( &head0, triple );
printf( "list0: " );
putc( '\n', display( head0, stdout ) );
printf( "list1: " );
putc( '\n', display( head1, stdout ) );
printf( "list2: " );
putc( '\n', display( head2, stdout ) );
printf( "list3: " );
putc( '\n', display( head3, stdout ) );
return 0;
}
The program output is
list1: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
list2: 10 -> 11 -> 12 -> 13 -> 14 -> null
list3: 15 -> 16 -> 17 -> null
list0: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14 -> 15 -> 16 -> 17 -> null
list1: null
list2: null
list3: null
list0: null
list1: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> null
list2: 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> null
list3: 12 -> 13 -> 14 -> 15 -> 16 -> 17 -> null
I did not spend my time to write a function that clears a list freeing all the allocated memory. I hope you can write such a function yourself.

Insertion Sort on Linked List in C

I am trying to perform Insertion Sort on linked list in C using following function, it gets stuck in a infinite loop. I debugged the code and found out that it works for the first pass and gets stuck in infinite loop in the second pass.
void insertion_sort()//Insertion Sort function
{
struct Node *p = root->next;
struct Node *a = NULL, *b = NULL;
while(p != NULL)
{
a = root;
while(a != p)
{
b = a;
a = a->next;
}
if(b != NULL)
b->next = a->next;
a->next = NULL;
struct Node *q = root;
struct Node* r = NULL;
while(p->data > q->data)
{
r = q;
q = q->next;
}
p->next = q;
if(r != NULL)
r->next = p;
p = p->next;
}
}
For starters it is a bad idea when a function depends on a global variable. In case of your program it means for example that you can not have two lists in one program.
I do not see where the pointer root is changed in the function insertion_sort. So even if all other code is valid nevertheless the function is incorrect because it does not change the pointer root when the value of the pointed node is unordered.
I can suggest the following solution shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Node
{
int data;
struct Node *next;
};
int push_front( struct Node **head, int data )
{
struct Node *node = malloc( sizeof( struct Node ) );
int success = node != NULL;
if ( success )
{
node->data = data;
node->next = *head;
*head = node;
}
return success;
}
void insertion_sort( struct Node **head )
{
for ( struct Node **current = head; *current != NULL; )
{
struct Node **sorted = head;
while ( *sorted != *current && !( ( *current )->data < ( *sorted )->data ) )
{
sorted = &( *sorted )->next;
}
if ( *sorted != *current )
{
struct Node *tmp = *current;
*current = ( *current )->next;
tmp->next = *sorted;
*sorted = tmp;
}
else
{
current = &( *current )->next;
}
}
}
FILE * output( struct Node *head, FILE *fp )
{
for ( ; head != NULL; head = head->next )
{
fprintf( fp, "%d -> ", head->data );
}
fputs( "null", fp );
return fp;
}
int main(void)
{
enum { N = 13 };
struct Node *head = NULL;
srand( ( unsigned int )time( NULL ) );
for ( int i = 0; i < N; i++ )
{
push_front( &head, rand() % N );
}
fputc( '\n', output( head, stdout ) );
insertion_sort( &head );
fputc( '\n', output( head, stdout ) );
return 0;
}
The program output might look like
1 -> 12 -> 0 -> 4 -> 0 -> 12 -> 3 -> 7 -> 12 -> 2 -> 5 -> 9 -> 7 -> null
0 -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 7 -> 7 -> 9 -> 12 -> 12 -> 12 -> null

C - How to split a linked list with struct type data

I have a problem that require Splitting a singly linked list into 2 part with a function: Split(n1, n2) where n1 = position of the element, n2 is number of elements to be split. I've managed to come up with an algorithm and a Testing program:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Node
{
int value;
struct Node *next;
};
int push_front( struct Node **head, int value )
{
struct Node *new_node = malloc( sizeof( struct Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->value = value;
new_node->next = *head;
*head = new_node;
}
return success;
}
void display( const struct Node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->value );
}
//puts( "null" );
}
struct ListPair
{
struct Node *head1;
struct Node *head2;
};
struct ListPair split( struct Node **head, size_t pos, size_t n )
{
struct ListPair p = { .head1 = NULL, .head2 = NULL };
struct Node **current1 = &p.head1;
struct Node **current2 = &p.head2;
for ( size_t i = 0; *head != NULL && i != pos; i++ )
{
*current2 = *head;
*head = ( *head )->next;
( *current2 )->next = NULL;
current2 = &( *current2 )->next;
}
while ( *head != NULL && n-- )
{
*current1 = *head;
*head = ( *head )->next;
( *current1 )->next = NULL;
current1 = &( *current1 )->next;
}
while ( *head != NULL )
{
*current2 = *head;
*head = ( *head )->next;
( *current2 )->next = NULL;
current2 = &( *current2 )->next;
}
return p;
}
int main(void)
{
const size_t N = 15;
struct Node *head = NULL;
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < N; i++ )
{
push_front( &head, rand() % N );
}
display( head );
putchar( '\n' );
struct ListPair p = split( &head, 6, 3 );
display( head );
display( p.head1 );
display( p.head2 );
return 0;
}
The result is:
12 -> 14 -> 3 -> 0 -> 12 -> 5 -> 4 -> 0 -> 2 -> 14 -> 1 -> 0 -> 6 -> 0 -> 5 -> null
null
5 -> 4 -> 0 -> 2 -> 14 -> null
12 -> 14 -> 3 -> 0 -> 12 -> 1 -> 0 -> 6 -> 0 -> 5 -> null
But don't know how to implement the above into my linked list, which is:
typedef struct address_t
{
char name[30];
char storage[5];
char screen[5];
int price;
} address;
typedef address elementtype;
typedef struct node node;
typedef struct node{
elementtype element;
node *next;
};
node *root, *cur, *prev;
Please help :(
Overview
As far as I understand the question you simply want to remove a sublist from a single linked list e.g. the list = el1 -> el2 -> el5 -> el6 -> el3 -> null. When you call split(list, 2, 2) the result will be two lists list and list1 with list = el1 -> el2 -> el3 -> null and list1 = el5 -> el6 -> null.
But what is not really clear is what the actual problem is you are facing, and what have you tried so far to make it work?
Answer
From how I read the question it is not really important, how the content of each list element looks like. So why don't you just take your struct Node from the example and replace the field int value by address value like the following:
typedef struct {
char name[30];
char storage[5];
char screen[5];
int price;
} address;
struct Node
{
address value;
struct Node *next;
};
There are a few issues in your code you might want to change.
1. Your split function sets the passed in pointer head to NULL. This might not be wanted behavior
2. You are returning a struct from split(...). Since everything in C is passed around by value you might consider passing a (double-)pointer to split(...) as well and put the resulted ListPair in there, because then the ListPair has not to be copied when returning from the function
3. Normally you would not use a _t for the struct name but not for the typedef itself.
4. You typedef the struct address_t and typedef the type with elementtype, but never used address
5. You have a typedef, that does not have a name
typedef struct node{
elementtype element;
node *next;
};
Just remove the typedef in that line, because you already did a typedef one line before.

Remove first node from a linked list and return it without allocating or deallocating memory.(C programming)

I am not allowed to deallocate memory or allocate new memory(the list has already been allocated for me). So in essence I am trying to write a function like,
struct node* returnAndRemoveFirstNode(struct node* head)
{
struct node* returned = head;
struct node* temp = head->next;
returned->next = NULL;
head = temp;
return returned;
}
This does not work, as when I set returned->next to null I am also setting head's next to null. I am not sure how to solve this problem, I am sure there are many ways to solve it just not sure how.
For a List in the form (1->2->3->4) both the original list and the returned node look like (1->Null)
//Here is the node struct in case you need it
//I am not allowed to alter the struct..
struct node{
int data;
struct node *next;
};
I am sure you do not understand correctly the original task.
Nevertheless a function that removes the first node from the list and returns it can look the following way
struct node * returnAndRemoveFirstNode( struct node **head )
{
struct node *returned = *head;
if ( *head != NULL )
{
*head = ( *head )-next;
returned->next = NULL;
}
return returned;
}
Pay attention to that in general the list can be empty. So the pointer to the head node can be equal to NULL.
If to follow the description in your comment
The original task is to remove all nodes from the list that contain a
specific data and add all of those nodes to a different list and
return it.
then the function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
int push_front( struct node **head, int data )
{
struct node *new_node = malloc( sizeof( struct node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = *head;
*head = new_node;
}
return success;
}
void output( struct node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
struct node * remove_if( struct node **head, int cmp( int data ) )
{
struct node *new_list = NULL;
for ( struct node **current = &new_list; *head != NULL; )
{
if ( cmp( ( *head )->data ) )
{
*current = *head;
*head = ( *head )->next;
( *current )->next = NULL;
current = &( *current )->next;
}
else
{
head = &( *head )->next;
}
}
return new_list;
}
int odd( int data )
{
return data % 2 != 0;
}
int even( int data )
{
return data % 2 == 0;
}
int main(void)
{
const int N = 10;
struct node *head = NULL;
for ( int i = N; i != 0; --i ) push_front( &head, i );
output( head );
putchar( '\n' );
struct node *even_head = remove_if( &head, even );
output( head );
output( even_head );
putchar( '\n' );
struct node *odd_head = remove_if( &head, odd );
output( head );
output( odd_head );
putchar( '\n' );
return 0;
}
The program output is
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
1 -> 3 -> 5 -> 7 -> 9 -> null
2 -> 4 -> 6 -> 8 -> 10 -> null
null
1 -> 3 -> 5 -> 7 -> 9 -> null
struct node* returnFirstNode(struct node** head)
{
struct node* returned = *head;
struct node* next = (*head)->next;
*head = next;
returned->next = NULL;
return returned;
}

Resources