how to connect a struct nodes(linked lists)? - c

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

Related

Partition a Linked List (C)

The problem asks us to split a Linked List based on a pivot value
(1->2->4->6->3->5 pivot = 5 ) => ( 1->2->4->3->5->6)
My Solution to the problem was to create 3 new linked list and split based on the pivot value. However I am not able to concatenate the 3 linked list together and let head point to the new concatenated linked list. Please guide me through on how I can concatenate the 3 linked list and let head point to the concatenated linked list.
void triPartition(ListNode** head, int pivot){
ListNode *cur;
ListNode ** Small = NULL;
ListNode ** Equal = NULL;
ListNode ** Large = NULL;
int Scount = 0 , Ecount = 0 , Lcount = 0;
cur = (*head);
if(cur == NULL)
{
return 0;
}
if(cur->next == NULL)
{
return 0;
}
while(cur != NULL)
{
if(cur->item == pivot)
{
insertNode(&Equal, Ecount, cur->item);
Ecount++;
}
else if(cur->item < pivot)
{
insertNode(&Small, Scount, cur->item);
Scount++;
}
else
{
insertNode(&Large, Lcount, cur->item);
Lcount++;
}
cur = cur->next;
}
This part of my solution does not work
*head = Small;
while((*Small)->next!=NULL)
{
Small = (*Small)->next;
}
(*Small)->next = Equal;
while((*Equal)->next!=NULL)
{
Equal = (*Equal)->next;
}
(*Equal)->next = Large;
}
It seems that no professional programmer are going tp help you. So we beginners should help each other ourselves.:)
Using your approach to the function implementation by means of creating at first three separate lists and then combining them in one list I can suggest the following function definition shown in the demonstration program below.
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode
{
int item;
struct ListNode *next;
} ListNode;
void clear( ListNode **head )
{
while (*head)
{
ListNode *current = *head;
*head = ( *head )->next;
free( current );
}
}
size_t assign( ListNode **head, const int a[], size_t n )
{
clear( head );
size_t i = 0;
for ( ; i != n && ( *head = malloc( sizeof( ListNode ) ) ) != NULL; i++)
{
( *head )->item = a[i];
( *head )->next = NULL;
head = &( *head )->next;
}
return i;
}
FILE *display( const ListNode * const head, FILE *fp )
{
for ( const ListNode *current = head; current != NULL; current = current->next)
{
fprintf( fp, "%d -> ", current->item );
}
fputs( "null", fp);
return fp;
}
void triPartition( ListNode **head, int pivot )
{
ListNode * small = NULL;
ListNode * equal = NULL;
ListNode * large = NULL;
ListNode ** small_ptr = &small;
ListNode ** equal_ptr = &equal;
ListNode ** large_ptr = &large;
for ( ListNode *current = *head; current != NULL; )
{
ListNode *tmp = current;
current = current->next;
tmp->next = NULL;
if ( tmp->item < pivot )
{
*small_ptr = tmp;
small_ptr = &( *small_ptr )->next;
}
else if ( pivot < tmp->item )
{
*large_ptr = tmp;
large_ptr = &( *large_ptr )->next;
}
else
{
*equal_ptr = tmp;
equal_ptr = &( *equal_ptr )->next;
}
}
*equal_ptr = large;
*small_ptr = equal;
*head = small;
}
int main( void )
{
int a[] = { 1, 2, 4, 6, 3, 5 };
ListNode *head = NULL;
assign( &head, a, sizeof( a ) / sizeof( *a ) );
fputc( '\n', display( head, stdout ) );
triPartition( &head, 5 );
fputc( '\n', display( head, stdout ) );
clear( &head );
}
The program output is
1 -> 2 -> 4 -> 6 -> 3 -> 5 -> null
1 -> 2 -> 4 -> 3 -> 5 -> 6 -> null

How to return the first node containing the item with maximum value in C linked list?

I am trying to return the first node that contains the item which has a maximum value. Here is my code,
struct ListNode* CreateNode(int item) {
struct ListNode* Newnode = (struct
ListNode*)malloc(sizeof(struct ListNode)); //allocate new node
Newnode->item = item;
Newnode->next = NULL;
return Newnode;}
struct ListNode* searchmaxvalNode (struct ListNode *head) {
struct ListNode *cur = head;
int max = head->item;
while(cur != NULL){
if((cur->item) < max){
max = cur->item;
}
cur = cur->next;
return cur;
}
return NULL;
}
struct ListNode { //list.h file
int item;
struct ListNode *next;
};
what is wrong with my searchmaxvalnode function?
For starters in general the pointer head can be equal to NULL. So your function can invoke undefined behavior because it will try to access memory using a null pointer.
Also this if statement
if((cur->item) < max){
max = cur->item;
}
is incorrect and does not make a sense. In fact it selects a minimum value.
Also this return statement
return cur;
at least shall be placed outside the while loop though it also does not make a sense because it returns a pointer to a current node instead of the returning a pointer to the node with the maximum value.
The function can look the following way.
struct ListNode * searchmaxvalNode ( struct ListNode *head )
{
struct ListNode *max = head;
if ( head != NULL )
{
while ( ( head = head->next ) != NULL )
{
if ( max->item < head->item ) max = head;
}
}
return max;
}
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct ListNode
{
int item;
struct ListNode *next;
};
struct ListNode * CreateNode( int item )
{
struct ListNode *Newnode = malloc( sizeof( struct ListNode ) );
if ( Newnode != NULL )
{
Newnode->item = item;
Newnode->next = NULL;
}
return Newnode;
}
int push_front( struct ListNode **head, int item )
{
struct ListNode *Newnode = CreateNode( item );
int success = Newnode != NULL;
if ( success )
{
Newnode->next = *head;
*head = Newnode;
}
return success;
}
void display( const struct ListNode *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->item );
}
puts( "null" );
}
struct ListNode * searchmaxvalNode( struct ListNode *head )
{
struct ListNode *max = head;
if ( head != NULL )
{
while ( ( head = head->next ) != NULL )
{
if ( max->item < head->item ) max = head;
}
}
return max;
}
int main(void)
{
struct ListNode *head = NULL;
srand( ( unsigned int )time( NULL ) );
const int N = 10;
for ( int i = 0; i < N; i++ )
{
push_front( &head, rand() % N );
}
display( head );
struct ListNode *max = searchmaxvalNode( head );
printf( "The maximum value stored in the list is %d\n", max->item );
return 0;
}
The program output is
1 -> 8 -> 2 -> 1 -> 4 -> 6 -> 4 -> 5 -> 8 -> 4 -> null
The maximum value stored in the list is 8

Having a hard time creating a function for lists in C

I am trying to create a function delz() which deletes a given number from the end of the list, I tried recursively and with a while loop and I can't figure it out.
Example: [ 3 | next ] - [ 4 | next ] - [ 3 | next ] - [ 7 | next ] -----> [ 3 | next ] - [ 4 | next ] - [ 7 | next ]
list delz (int val, list l) {
if(l == NULL)
return NULL;
else {
list head = l;
list tmp = l;
list tail;
list temp;
while(l != NULL){
if(l->value == val) {
list tail = l->next;
head->next = tail;
}
temp = head;
head = tmp;
l = l->next;
}
return head;
}
}
typedef struct node {
int value;
struct node *next;
} node, *list;
The function will be simpler if to pass to the function the pointer to the head node by reference.
Here is a demonstrative program. I used my own singly-linked list definition because you did not show your own. Also it is a bad idea to introduce a typedef for a pointer type.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int val;
struct Node *next;
};
void assign( struct Node **head, const int a[], size_t n )
{
if ( *head )
{
struct Node *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
for ( size_t i = 0; i < n; i++ )
{
*head = malloc( sizeof( struct Node ) );
( *head )->val = a[i];
( *head )->next = NULL;
head = &( *head )->next;
}
}
void display( const struct Node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->val );
}
puts( "null" );
}
int remove_last( struct Node **head, int val )
{
struct Node **target = NULL;
for ( ; *head != NULL; head = &( *head )->next )
{
if ( ( *head )->val == val ) target = head;
}
int success = target != NULL;
if ( success )
{
struct Node *tmp = *target;
*target = ( *target )->next;
free( tmp );
}
return success;
}
int main(void)
{
int a[] = { 3, 4, 3, 7 };
const size_t N = sizeof( a ) / sizeof( *a );
struct Node *head = NULL;
assign( &head, a, N );
display( head );
int val = 3;
if ( remove_last( &head, val ) )
{
printf( "The last node with the value %d is removed.\n", val );
}
display( head );
return 0;
}
The program output is
3 -> 4 -> 3 -> 7 -> null
The last node with the value 3 is removed.
3 -> 4 -> 7 -> null

How to delete multiple occurrences of multiple variables in a linked list in c

I am a beginner in c programming and i have been trying for several days to solve the following question:
how to remove numbers that appear at least 3 times in the following list:
3→3→1→2→4→3→5→3→5→4
which makes the result:
1→2→4→5→5→4.
Now i know how to delete multiple occurrences of "one" key in a linked list, for example deleting all occurrences of "1" in the linked list, but can't seem to understand how to delete multiple occurrences of multiple variables. It's just killing me. I would really appreciate it if anyone could help. thanks in advance.
It seems nobody hurries to help you.:)
It is simpler to write the function if to pass the pointer head to the function by reference.
Here is a demonstrative program that shows how the function can be implemented.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
int insert( 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 out( struct Node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
void remove_repetitive( struct Node **head )
{
const size_t LIMIT = 3;
while ( *head != NULL )
{
size_t count = 1;
int data = ( *head )->data;
for ( struct Node *node = ( *head )->next;
count < LIMIT && node != NULL; node = node->next )
{
if ( node->data == data ) ++count;
}
if ( count == LIMIT )
{
for ( struct Node **node = head; *node != NULL; )
{
if ( ( *node )->data == data )
{
struct Node *tmp = *node;
*node = ( *node )->next;
free( tmp );
}
else
{
node = &( *node )->next;
}
}
}
else
{
head = &( *head )->next;
}
}
}
int main(void)
{
struct Node *head = NULL;
int a[] = { 4, 5, 3, 5, 3, 4, 2, 1, 3, 3 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
insert( &head, a[i] );
}
out( head );
remove_repetitive( &head );
out( head );
return 0;
}
The program output is
3 -> 3 -> 1 -> 2 -> 4 -> 3 -> 5 -> 3 -> 5 -> 4 -> null
1 -> 2 -> 4 -> 5 -> 5 -> 4 -> null
The function remove_repetitive can be splitted out into two functions as it is shown below.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
int insert( 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 out( struct Node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
void remove_all( struct Node **head, int data )
{
while ( *head != NULL )
{
if ( ( *head )->data == data )
{
struct Node *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
else
{
head = &( *head )->next;
}
}
}
void remove_repetitive( struct Node **head )
{
const size_t LIMIT = 3;
while ( *head != NULL )
{
size_t count = 1;
int data = ( *head )->data;
for ( struct Node *node = ( *head )->next;
count < LIMIT && node != NULL; node = node->next )
{
if ( node->data == data ) ++count;
}
if ( count == LIMIT )
{
remove_all( head, data );
}
else
{
head = &( *head )->next;
}
}
}
int main(void)
{
struct Node *head = NULL;
int a[] = { 4, 5, 3, 5, 3, 4, 2, 1, 3, 3 };
const size_t N = sizeof( a ) / sizeof( *a );
for ( size_t i = 0; i < N; i++ )
{
insert( &head, a[i] );
}
out( head );
remove_repetitive( &head );
out( head );
return 0;
}
The program output is the same as shown above.

Delete a Node which is multiple of a given number with recursion [C programming]

I'm finding troubles trying to implement a function, this is what the program should do:
The user must first input an integer number (this number is not added to the list).
Then, I have to write a function which deletes recursively all the nodes in the list that are multiple of the input number.
This is my current code:
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0
#define bool int
typedef struct node {
int data;
struct node *next;
} Node;
void addToHead(Node **head, int value);
void printList(Node *head);
bool isMultipleOf(int value, int n);
void deleteMultipleOfNNodes(Node **head, int n);
int main() {
// Create head
Node *head = NULL;
int loop = true;
int input;
// The value whose multiples must be deleted from the list
int n;
scanf("%d", &n);
while (loop) {
scanf("%d", &input);
// End loop - print list
if (input < 0) {
deleteMultipleOfNNodes(&head, n);
printList(head);
loop = false;
} else {
// Add value to the head
addToHead(&head, input);
}
}
return 0;
}
void addToHead(Node **head, int value) {
Node *temp;
if (*head != NULL) {
// Create new node
Node *newNode = (Node*) malloc(sizeof(Node));
// Set new node data
newNode -> data = value;
// New node links to the head
newNode -> next = *head;
// New node is now the head of the list
*head = newNode;
} else {
// Create head
*head = (Node*) malloc(sizeof(Node));
// Set head data
(*head) -> data = value;
// Head links to NULL
(*head) -> next = NULL;
}
}
void printList(Node *head) {
Node *temp = head;
while (temp != NULL) {
if (temp -> next != NULL) {
printf("%d -> ", temp->data);
} else {
printf("%d -> NULL", temp -> data);
}
temp = temp->next;
}
}
bool isMultipleOf(int value, int n) {
// While the value is greater than zero, keep on subtracting the number
while (value > 0) {
value -= n;
}
return (value == 0);
}
void deleteMultipleOfNNodes(Node **head, int n) {
// ========= CODE ================
}
Thank you in advance for your help!
The function can look very simple
void deleteMultipleOfNNodes( Node **head, int n )
{
Node *tmp = *head;
if ( tmp != NULL )
{
tmp->data % n == 0 ? ( *head ) = ( *head )->next, free( tmp )
: ( void )( head = &( *head )->next );
deleteMultipleOfNNodes( head, n );
}
}
Pay attention to that this function
bool isMultipleOf(int value, int n) {
// While the value is greater than zero, keep on subtracting the number
while (value > 0) {
value -= n;
}
return (value == 0);
}
is invalid in general case because either value or n can be negative.
So define the function like
bool isMultipleOf( int value, int n )
{
return value % n == 0;
}
In this case the function above can be rewritten like
void deleteMultipleOfNNodes( Node **head, int n )
{
Node *tmp = *head;
if ( tmp != NULL )
{
isMultipleOf( tmp->data, n ) ? ( *head ) = ( *head )->next, free( tmp )
: ( void )( head = &( *head )->next );
deleteMultipleOfNNodes( head, n );
}
}
The function addToHead is too complicated. It can be written the following way
bool addToHead(Node **head, int value)
{
Node *newNode = malloc( sizeof( Node ) );
bool success = newNode != NULL;
if ( success )
{
newNode -> data = value;
newNode -> next = *head;
*head = newNode;
}
return success;
}
Here is a demonstrative program. It contains only those functions that are required to demonstrate the recursive function.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node {
int data;
struct node *next;
} Node;
bool addToHead(Node **head, int value)
{
Node *newNode = malloc( sizeof( Node ) );
bool success = newNode != NULL;
if ( success )
{
newNode -> data = value;
newNode -> next = *head;
*head = newNode;
}
return success;
}
bool isMultipleOf( int value, int n )
{
return value % n == 0;
}
void deleteMultipleOfNNodes( Node **head, int n )
{
Node *tmp = *head;
if ( tmp != NULL )
{
isMultipleOf( tmp->data, n ) ? ( *head ) = ( *head )->next, free( tmp )
: ( void )( head = &( *head )->next );
deleteMultipleOfNNodes( head, n );
}
}
void printList( const Node *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d --> ", head->data );
}
puts( "NULL" );
}
int main(void)
{
Node *head = NULL;
const int N = 10;
for ( int i = N; i != 0; i-- )
{
addToHead( &head, i );
}
printList( head );
deleteMultipleOfNNodes( &head, 2 );
printList( head );
return 0;
}
Its output is
1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> 10 --> NULL
1 --> 3 --> 5 --> 7 --> 9 --> NULL

Resources