Remove value from a List - c

I'm writing a program which creates lists, print it and remove from the list (3 functions).
Print and pushBack are fine, they work nice but I can't figure out how to pick up a number to remove from the list in removeFromList() function.
Don't pay attention on names (like client, socket), it's for my client-server application to save active sockets (that's why I need to remove them from a list when client has disconnected).
Here I have 2 structures: listElement and clientList (which contains a pointer to head element of listElement)
struct listElement
{
SOCKET socket;
struct listElement* next;
};
struct clientList
{
listElement * head;
};
My pushBack function:
int pushBackŠ”lient(struct clientList* list, int socket)
{
struct listElement* newClient = (struct listElement*)malloc(sizeof(struct listElement));
struct listElement* currentElement = list->head;
newClient->socket = socket;
newClient->next = 0;
do
{
// IT'S PUSHBACK
if (list->head == 0)
{
list->head = newClient;
break;
}
while (currentElement->next != 0)
{
currentElement = currentElement->next;
}
currentElement->next = newClient;
} while (false);
return 0;
}
My print:
void print(struct clientList* list)
{
struct listElement* currentElement = list->head;
while (currentElement != 0)
{
printf("%d\n", currentElement->socket);
currentElement = currentElement->next;
}
}
And the function I have a problem with (I made debug messages to see if a "socket" was added correctly). I suppose I don't need the first 3 lines but not sure.
Updated13/05/2017
void removeFromList(struct clientList* list, int socket)
{
struct listElement* currentElement = list->head;
do
{
if (list->head == 0)
{
return;
}
while (currentElement != 0 && currentElement->next != 0)
{
if (currentElement->socket == socket)
{
printf("currentElement == %d\n", currentElement);
currentElement = currentElement->next;
printf("currentElement == %d\n", currentElement);
free(currentElement);
//break; // if I only want to remove the first socket?
}
currentElement = currentElement->next;
}
} while (false);
}
Thank you.

The function removeFromList is wrong at least because this condition of the while statement can be equal to false when the list contains only one element. In this case even this one element contains the target vakue it will not be removed.
while (currentElement != 0 && currentElement->next != 0)
The functions can look as it is shown in the demonstrative program.
#include <stdio.h>
#include <stdlib.h>
typedef int SOCKET;
struct listElement
{
SOCKET socket;
struct listElement *next;
};
struct clientList
{
struct listElement *head;
};
int pushBackClient( struct clientList *list, SOCKET socket )
{
struct listElement *newClient = malloc( sizeof( struct listElement ) );
int success = newClient!= NULL;
if ( success )
{
newClient->socket = socket;
newClient->next = NULL;
struct listElement **current = &list->head;
while ( *current != NULL ) current = &( *current )->next;
*current = newClient;
}
return success;
}
int removeFromList( struct clientList *list, SOCKET socket )
{
int success;
struct listElement **current = &list->head;
while ( *current != NULL && ( *current )->socket != socket )
{
current = &( *current )->next;
}
if ( ( success = *current != NULL ) )
{
struct listElement *tmp = *current;
*current = ( *current )->next;
free( tmp );
}
return success;
}
void print(struct clientList *list)
{
for ( struct listElement *current = list->head;
current != NULL;
current = current->next )
{
printf( "%d ", current->socket );
}
}
int main(void)
{
const int N = 10;
struct clientList list = { NULL };
for ( int i = 0; i < N; i++ ) pushBackClient( &list, i );
print( &list );
putchar( '\n' );
for ( int i = 0; i < N; i++ )
{
if ( i % 2 == 0 ) removeFromList( &list, i );
}
print( &list );
putchar( '\n' );
for ( int i = 0; i < N; i++ )
{
if ( i % 2 == 1 ) removeFromList( &list, i );
}
print( &list );
putchar( '\n' );
return 0;
}
The program output is
0 1 2 3 4 5 6 7 8 9
1 3 5 7 9
You need at least to add a function that will free all elements of the list.

For your remove function I suggest something like this:
void removeFromList(struct clientList* list, int socket)
{
struct listElement* aux, prev;
if(list->head == 0)
return;
aux = list->head;
prev = aux;
while(aux != 0){
if(aux->socket == socket) {
prev->next = aux->next;
free(aux);
break; // if you only want to remove the first socket
}
prev = aux;
aux = aux->next;
}
}
As for your list structure, I suggest using a structure of structs, like follows:
struct list
{
int numberOfElements;
NODE * first;
} LIST;
struct node
{
ELEMENT * info;
NODE * prev; // If you want to have a double connection between the nodes
NODE * next;
} NODE;
struct element
{
int id;
/* Other Properties */
} ELEMENT;
It should give you a better control of your list.

Related

Queue implementing by linked list in c

I am implementing queue with a linked list but I am facing problem in the insertion() function. I am able to insert only one data, whenever I insert another data then again previous data insert whatever did I insert at first time.
#include <stdio.h>
#include <stdlib.h>
struct Queue
{
int data;
struct Queue *next;
};
struct Queue *rear = NULL;
struct Queue *front = NULL;
void insertion(int data)
{
struct Queue *n;
n = (struct Queue *)malloc(sizeof(struct Queue));
n->data = data;
n->next = NULL;
if (rear == NULL)
{
front = n;
rear = n;
}
else
{
rear->next = n;
rear = n;
}
}
void deletion()
{
if (front == NULL)
printf("\n Underflow");
else if (front == rear)
{
front = NULL;
rear = NULL;
}
else
front = front->next;
}
void viewList()
{
struct Queue *t = front;
if (t == NULL)
printf("\n there is no item for view...............");
else
{
while (t != NULL)
{
printf(" %d", front->data);
t = t->next;
}
}
}
int main()
{
struct Queue *q = NULL;
insertion(5);
insertion(10);
// deletion();
viewList();
printf("\n");
viewList();
return 0;
}
The function deletion produces a memory leak because it does not free the memory of the deleted node. The function can look at least like
void deletion() {
if(front == NULL)
printf("\n Underflow");
else
{
stuct Queue *n = front;
front = front->next;
if ( front == NULL ) rear = NULL;
free( n );
}
}
Within the function viewList you are always outputting the value stored in the node pointed to by the pointer front
printf(" %d", front->data);
You have to write
printf(" %d", t->data);
This declaration in main
struct Queue *q = NULL;
is redundant and does not make a sense.
Pay attention to that it is a bad idea when functions depend on global variables. You could define the queue the following way
struct Node
{
int data;
struct Node *next;
};
struct Queue
{
struct Node *front;
struct Node *rear;
};
And in main you could define an object of the queue the following way
struct Queue queue = { .front = NULL, .rear = NULL };
And the functions should be rewritten such a way that they would accept a pointer to the queue. For example
int insertion( struct Queue *queue, int data );
The function can be defined like
int insertion( struct Queue *queue, int data )
{
struct Node *new_node = malloc( sizeof( struct Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = NULL;
if ( queue->front == NULL )
{
queue->front = new_node;
}
else
{
queue->rear->next = new_node;
}
queue->rear = new_node;
}
return success;
}
And the function will be called like
int main( void )
{
struct Queue queue = { .front = NULL, .rear = NULL };
insertion( &queue, 5 );
insertion( &queue, 10 );
//...
you can check the returned value of the function to determine whether the insertion was successful as for example.
if ( !insertion( &queue, 5 ) ) puts( "Error. Not enough memory." );
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct Queue
{
struct Node *front;
struct Node *rear;
};
int insertion( struct Queue *queue, int data )
{
struct Node *new_node = malloc( sizeof( struct Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = NULL;
if ( queue->front == NULL )
{
queue->front = new_node;
}
else
{
queue->rear->next = new_node;
}
queue->rear = new_node;
}
return success;
}
int empty( const struct Queue *queue )
{
return queue->front == NULL;
}
void viewList( const struct Queue *queue )
{
if ( empty( queue ) )
{
printf("\n there is no item for view...............");
}
else
{
for ( struct Node *current = queue->front; current != NULL; current = current->next )
{
printf( " %d", current->data );
}
}
}
int main(void)
{
struct Queue queue = { .front = NULL, .rear = NULL };
insertion( &queue, 5 );
insertion( &queue, 10 );
viewList( &queue );
return 0;
}
The program output is
5 10

A C function that inserts number into a linked list in ascending order

This is my function:
void IntListInsertInOrder (IntList L, int v)
{
struct IntListNode *n = newIntListNode (v);
if (L->first == NULL) { //case a, empty list
L->first = L->last = n;
L->size ++;
return;
}
else if (v <= L->first->data) { // case b, smallest value
n->next = L->first;
L->first = n;
}
else if (v >= L->last->data) { // case c, largest value
L->last->next = n;
L->last = n;
}
else if (v > L->first->data && v <= L->first->next->data) { // case d, second-smallest value
n->next = L->first->next;
L->first->next = n;
}
else { //case f, value in the middle
struct IntListNode *curr = L->first;
while (curr->next->data < v) {
curr = curr->next;
}
n->next = curr->next;
curr->next = n;
}
L->size ++;
return;
}
when i put random lists of 10 numbers into it, 3/10 sorted correctly. the errors seem to be in the last part but it looks exactly like solutions i found online.
OK I figured it out. I forgot to add&& curr-> != NULLin the condition of the last while loop. After I added that all the test cases passed.
Your function is too complicated, has many if conditions and as a result it is error-prone and unreadable.
You did not show the list definition but I can guess that you have a two-sided singly-linked list because nowhere in the code there is a reference to a data member named prev.
Here is a demonstrative program that shows how the function can be simply defined.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Node
{
int data;
struct Node *next;
} Node;
typedef struct List
{
Node *head;
Node *tail;
size_t size;
} List;
int insert_in_order( List *list, int data )
{
Node *new_node = malloc( sizeof( Node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
Node **current = &list->head;
while ( *current != NULL && !( data < ( *current )->data ) )
{
current = &( *current )->next;
}
new_node->next = *current;
if ( *current == NULL )
{
list->tail = new_node;
}
*current = new_node;
++list->size;
}
return success;
}
void clear( List *list )
{
while ( list->head != NULL )
{
Node *current = list->head;
list->head = list->head->next;
free( current );
}
}
void display( const List *list )
{
printf( "There are %zu nodes in the list\n", list->size );
printf( "They are: " );
for ( const Node *current = list->head; current != NULL; current = current->next )
{
printf( "%d -> ", current->data );
}
puts( "null" );
}
int main(void)
{
List list = { .head = NULL, .tail = NULL, .size = 0 };
srand( ( unsigned int )time( NULL ) );
const size_t N = 10;
for ( size_t i = 0; i < N; i++ )
{
insert_in_order( &list, rand() % ( int )N );
}
display( &list );
clear( &list );
return 0;
}
The program output might look like
There are 10 nodes in the list
They are: 1 -> 2 -> 3 -> 3 -> 6 -> 6 -> 7 -> 8 -> 8 -> 9 -> null

Delete specific element linked list

Can you help me to understand why this function doesn't delete a specific element in the linked list? What am I doing wrong?
typedef struct str_node{
int data;
struct str_node *next;
}node;
...
node *head;
head = malloc(sizeof(node));
...
void delete_spec(node *a){
int num;
node *tmp;
tmp = a;
printf("Insert number to eliminate: ");
scanf("%d",&num);
while(tmp!=NULL){
if(tmp->data == num){
tmp = tmp->next->next;
}
tmp = tmp->next;
}
}
For starters it is unclear what the allocation is doing here
node *head;
head = malloc(sizeof(node));
The pointer head shall be initially set to NULL
node *head = NULL;
and new nodes shall be inserted in the list by the function that inserts new values in the list.
The function that deletes nodes from the list shall not issue any prompt. It is the caller of the function that will ask the user to specify the value that will be deleted from the list and then call the function passing the specified value. So the function should have two parameters: pointer to the pointer to the head node and the integer value that shall be deleted from the list.
The function can be defined the following way
void delete_spec( node **head, int data )
{
while ( *head != NULL )
{
if ( ( *head )->data == data )
{
node *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
else
{
head = &( *head )->next;
}
}
}
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
typedef struct str_node
{
int data;
struct str_node *next;
} node;
int push_front( node **head, int data )
{
node *new_node = malloc( sizeof( node ) );
int success = new_node != NULL;
if ( success )
{
new_node->data = data;
new_node->next = *head;
*head = new_node;
}
return success;
}
void delete_spec( node **head, int data )
{
while ( *head != NULL )
{
if ( ( *head )->data == data )
{
node *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
else
{
head = &( *head )->next;
}
}
}
void display( node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
int main(void)
{
node *head = NULL;
int a[] = { 1, 3, 5, 7, 1, 2, 3, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
push_front( &head, a[i] );
}
display( head );
delete_spec( &head, 1 );
display( head );
return 0;
}
Its output is
1 -> 3 -> 2 -> 1 -> 7 -> 5 -> 3 -> 1 -> null
3 -> 2 -> 7 -> 5 -> 3 -> null
public class LL5 {
Node head;
int size;
LL5(){
this.size = 0;
}
class Node{
String data;
Node next;
Node(String data){
this.data = data;
this.next = null;
size++;
}
}
public void push(String data) {
Node newNode = new Node(data);
if(head == null) {
head = newNode;
return;
}
newNode.next = head;
head = newNode;
}
public void deleteelement(String data) {
Node cur = head;
Node x = cur.next;
Node y = x.next;
if(data == head.data) {
head = head.next;
}
else if(x.data == data) {
head.next = y;
}
else{
while(y.data != data) {
x = x.next;
y = y.next;
}
x.next = y.next;
}
}
public void printList() {
if(head == null) {
System.out.println("list is empty");
return;
}
Node cn = head;
while(cn != null) {
System.out.print(cn.data + " -> ");
cn = cn.next;
}
System.out.print("null");
}
public static void main(String[] args) {
LL5 obj = new LL5();
obj.push("1");
obj.push("2");
obj.push("3");
obj.push("4");
obj.push("5");
obj.push("6");
obj.push("7");
obj.push("8");
obj.push("9");
obj.push("10");
System.out.println("before delete");
obj.printList();
System.out.println();
System.out.println("After delete");
obj.deleteelement("10");
obj.printList();
}
}
delete_spec does not modify in anyway the input list. also: it does not free any memory.
in order to actually delete a node you must:
1. free its memory.
2. modify the list so the "next" pointers are updated. in order to update the list, you must provide the delete function the address of the head so it can modify also head.
something like this:
void delete_spec(node **a){
int num;
node *tmp;
if (a == NULL || *a == NULL) return;
tmp = *a;
printf("Insert number to eliminate: ");
scanf("%d",&num);
if (tmp->data == num)
{
*a = (*a)->next;
free(tmp);
return;
}
while(tmp->next!=NULL){
if(tmp->next->data == num){
node* tmp2 = tmp->next;
tmp->next = tmp->next->next;
free(tmp2);
}
tmp = tmp->next;
}
}

merge two sorted linked list into one linked list (recursion)

I had to write a recursive function that receives two sorted lists:
typedef struct listNode {
int* dataPtr;
struct listNode* next;
} ListNode;
typedef struct list
{
ListNode* head;
ListNode* tail;
} List;
and merge them into one sorted list.
I wrote these functions:
void mergeRec(ListNode* head1, ListNode* head2, ListNode* mergedList)
{
if (head1 == NULL && head2 == NULL)
return;
else if (head1 == NULL) {
mergedList->next = head2;
head2 = head2->next;
}
else if (head2 == NULL) {
mergedList->next = head1;
head1 = head1->next;
}
else if (*(head1->dataPtr) > *(head2->dataPtr)) {
mergedList->next = head1;
head1 = head1->next;
}
else
{
mergedList->next = head2;
head2 = head2->next;
}
mergeRec(head1, head2, mergedList->next);
}
List merge(List lst1, List lst2)
{
List mergedList;
makeEmptyList(&mergedList);
mergeRec(lst1.head, lst2.head, mergedList.head);
return mergedList;
}
Now, the problem I have with the recursive function is that at the first call when merged list is pointing to null, so obviously when I write something like mergeList->next I will get a running bug.
I tried to solve it by adding the following condition in the recursion:
if (mergedList == NULL)
{
if (*(head1->dataPtr) > *(head2->dataPtr))
{
mergedList = head1;
head1 = head1->next;
}
else
{
mergedList = head2;
head2 = head2->next;
}
}
but I got this error:
"Exception thrown at 0x00661EB9 in q2d.exe: 0xC0000005: Access violation writing location 0x01000F48."
I can't tell the problem, or how do I solve it.
I would very much appreciate your help.
Thanks!
For starters it is entirely unclear why in this structure there is a data member of type int *
typedef struct listNode {
int* dataPtr;
struct listNode* next;
}List;
instead of just of type int
typedef struct listNode {
int data;
struct listNode* next;
}List;
Nevertheless, the functions merge and mergeRec are invalid because they deal with copies of values of lists and of pointers list1.head, list2.head, and mergedList.head.
List merge(List lst1, List lst2)
mergeRec(lst1.head, lst2.head, mergedList.head);
Moreover the pointers list1.tail, list2.tail, and mergedList.tail are ignored.
I can suggest the following solution shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
typedef struct listNode
{
int *dataPtr;
struct listNode *next;
} ListNode;
typedef struct list
{
ListNode *head;
ListNode *tail;
} List;
void makeEmpty( List *list )
{
list->head = list->tail = NULL;
}
int push( List *list, int data )
{
ListNode *current = malloc( sizeof( ListNode ) );
int success = current != NULL;
if ( success )
{
current->dataPtr = malloc( sizeof( int ) );
success = current->dataPtr != NULL;
if ( success )
{
*current->dataPtr = data;
current->next = NULL;
if ( list->head == NULL )
{
list->head = list->tail = current;
}
else
{
list->tail = list->tail->next = current;
}
}
else
{
free( current );
current = NULL;
}
}
return success;
}
List merge( List *first, List *second )
{
List result;
makeEmpty( &result );
if ( ( second->head != NULL ) &&
( first->head == NULL || *second->head->dataPtr < *first->head->dataPtr ) )
{
result.head = result.tail = second->head;
second->head = second->head->next;
if ( second->head == NULL ) second->tail = NULL;
}
else if ( first->head != NULL )
{
result.head = result.tail = first->head;
first->head = first->head->next;
if ( first->head == NULL ) first->tail = NULL;
}
if ( !( first->head == NULL && second->head == NULL ) )
{
List tmp = merge( first, second );
result.head->next = tmp.head;
result.tail = tmp.tail;
}
return result;
}
void output( const List *list )
{
for ( const ListNode *current = list->head; current != NULL; current = current->next )
{
printf( "%d ", *current->dataPtr );
}
puts( "NULL" );
}
int main(void)
{
List even_numbers;
List odd_numbers;
makeEmpty( &even_numbers );
makeEmpty( &odd_numbers );
const int N = 10;
for ( int i = 0; i < N; i++ )
{
i % 2 == 0 ? push( &even_numbers, i )
: push( &odd_numbers, i );
}
printf( "even_numbers: " ); output( &even_numbers );
printf( "odd_numbers: " ); output( &odd_numbers );
List all_numbers = merge( &even_numbers, &odd_numbers );
printf( "all_numbers: " ); output( &all_numbers );
printf( "even_numbers: " ); output( &even_numbers );
printf( "odd_numbers: " ); output( &odd_numbers );
return 0;
}
The program output is
even_numbers: 0 2 4 6 8 NULL
odd_numbers: 1 3 5 7 9 NULL
all_numbers: 0 1 2 3 4 5 6 7 8 9 NULL
even_numbers: NULL
odd_numbers: NULL

how to connect a struct nodes(linked lists)?

i want to make a new node that is a copy of Node_1 connected to Node_2
, the problem is that i need to choose elemenets in each node that
accept a specific condition thhat i insert in the connection function
. for example if i have two nodes that i want to connect to each other
(the second one at the end of the first one) , but i want to chose the
elements in each node that are for example odd ! (for example : first
linked list has the following elements(1 2 3 ) , and the second linked
list has the following elements (4 5 6) then i want to have a new linked list >that has the following elements : (1 3 5)
now my main problem is that i need to work with pointers to
functions because each time i want to give the function different
conditions .
i wrote this function with the assumption that i have a
ConditionFunction, but actually i an kinda stuck on how to make a
ConditionFunction in the main function that can actually do what i
want :/ (for example linke only the odd numbers)
i wrote this function to connect the two linked lists :
// the struct:
typedef struct node_t* Node;
struct node_t {
Element element;
Node next;
};
// ConditionNode a pointer to a function that has condition
// CopyNode a pointer to a function that copy's the node
Node concatLists(Node Node_1,Node Node_2,ConditionNode ConditionFunction,CopyNode copyFunction,void* condition){
Node currentNode=NULL;
Node* New_Node=NULL;
Node head=NULL;
while(Node_1!=NULL){
if(ConditionFunction(Node_1->element,condition)==0){
Node_Result=create_node(&New_Node);
if(head==NULL){
head=New_Node;
currentNode=New_Node;
}
currentNode->next=New_Node;
currentNode=New_Node;
Node_1=GetNextNode(Node_1);
}
else{
Node_1=GetNextNode(Node_1);
}
}
while(Node_2!=NULL){
if(CmpFunction(Node_2->element,condition)!=0){
if(head==NULL){
head=New_Node;
currentNode=New_Node;
}
currentNode->next=New_Node;
currentNode=New_Node;
Node_2=GetNextNode(Node_2);
} else {
Node_1=GetNextNode(Node_1);
}
}
return head;
}
Node_Result create_node(Node* CreatedNode) {
Node newNode = malloc(sizeof(*newNode));
if(!newNode) {
return MEM_PROBLEM;
}
newNode->element =0;
newNode->next = NULL;
*CreatedNode=newNode;
return NODE_SUCCESS;
}
Node GetNextNode(Node node){
if(node==NULL){
return NULL;
}
return node->next;
}
i wrote an example but i think it is wrong :\
int main(){
int array_1[3]={1,2,3};
int array_2[4]={4,5,6,7};
Node head_1=createAllNode(array_1,3);
Node head_2=createAllNode(array_2,4);
int num=2;
Node oddhead=concatLists(head_1,head_2,&copyInt,&checkIfOdd,&num);
printIntElements(oddhead);
return 0;
}
static Node createAllNode(int* array,int len){
Node head;
Node_Result result=create_node(&head);
if(result!=NODE_SUCCESS){
return NULL;
}
Node new_node=NULL;
int j=0;
while(len){
/*int *num=malloc(sizeof(*num));
if(num==NULL){
return NULL;
} */
int element=array[j];
head->element=*(int *)element;
if(j != len-1){
result=create_node(&new_node);
}
if(Node_Result!=NODE_SUCCESS){
return NULL;
}
head->next=new_node;
head=new_node;
new_node=GetNextNode(new_node);
j++;
len--;
}
return head;
}
static void* copyInt(void* num){
int* newInt=malloc(sizeof(*newInt));
*newInt=*(int*)num;
return newInt;
}
/*
static bool PrimaryIntNode(void*num1,void* num2){
}
*/
static void printIntElements(Node head){
while(head!=NULL){
printf("%d",(int*) head->element);
head=GetNextNode(head);
}
}
static bool checkIfOdd(Element num1,int num2){
int num=*(int *)num1;
if(num<0){
num *=-1;
}
return num % num2 != 0;
}
and i call the coonect list function like this in the main function :
Node oddhead=concatLists(head_1,head_2,&copyNode,&checkifIdd,&num);
can anyone just show me a correct example oh how actually use a
function like this in main !! because i get all kinda of errors in
eclipse ..
I will not use your definitions because they are confusing. I will just demonstrate how two lists can be concatenated by selecting nodes that satisfy some condition. You can use the presented demonstrative program as a base for your own list implementation.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void insert( struct node **head, const int a[], size_t n )
{
if ( *head != NULL ) head = &( *head )->next;
for ( size_t i = 0; i < n; i++ )
{
struct node *tmp = malloc( sizeof( struct node ) );
tmp->data = a[i];
tmp->next = *head;
*head = tmp;
head = &( *head )->next;
}
}
struct node * concatLists( struct node *head1, struct node *head2, int cmp( struct node * ) )
{
struct node *head = NULL;
struct node **current = &head;
for ( ; head1 != NULL; head1 = head1->next )
{
if ( cmp( head1 ) )
{
*current = malloc( sizeof( struct node ) );
( *current )->data = head1->data;
( *current )->next = NULL;
current = &( *current )->next;
}
}
for ( ; head2 != NULL; head2 = head2->next )
{
if ( cmp( head2 ) )
{
*current = malloc( sizeof( struct node ) );
( *current )->data = head2->data;
( *current )->next = NULL;
current = &( *current )->next;
}
}
return head;
}
void output( struct node *head )
{
for ( ; head != NULL; head= head->next )
{
printf( "%d ", head->data );
}
}
int odd( struct node *n )
{
return n->data % 2;
}
int main( void )
{
struct node *head1 = NULL;
struct node *head2 = NULL;
int a1[] = { 1, 2, 3 };
int a2[] = { 4, 5, 6 };
const size_t N1 = sizeof( a1 ) / sizeof( *a1 );
const size_t N2 = sizeof( a2 ) / sizeof( *a2 );
insert( &head1, a1, N1 );
insert( &head2, a2, N2 );
struct node *head3 = concatLists( head1, head2, odd );
output( head1 );
putchar( '\n' );
output( head2 );
putchar( '\n' );
output( head3 );
putchar( '\n' );
return 0;
}
The program output is
1 2 3
4 5 6
1 3 5

Resources