C rotate linked list by user choice - c

I wrote a program that get from a user numbers to linked list and number for how much to rotate each node in lust for the left. and I was only succeeded to do that but not in a circle. and my program need to be abale to move the node more left then the lenght of the list in circles.
someone know how can i fix my program??. (the function that need to be fixed is the "RotateALinkedList" function). i mean if the user want to move the list 4 times left the first node gonna start from the last node.
#include<stdio.h>
#include<stdlib.h>
typedef struct numbers_list
{
int data;
struct numbers_list* next;
}number;
void RotateALinkedList(number** head, int node); //the function that rotate the linked list
int CreateLinkedList(number** head, int iNumberofNode);
int attachToEnd(number** head, int k);
void PrintTheList(number* pNode);
void FreeAllocatedMemory(number** head);
int main(void)
{
int list_len = 0;
int data = 0;
number* head = NULL;
printf("How many nodes in list? ");
scanf("%d", &list_len);
getchar();
CreateLinkedList(&head, list_len);
printf("Choose a number k, and the list will be rotated k places to the left: ");
scanf("%d", &data);
getchar();
if (data <= list_len)
{
RotateALinkedList(&head, data);
PrintTheList(head);
}
else
{
printf("Please Enter Valid number of node\n");
}
FreeAllocatedMemory(&head);
getchar();
return 0;
}
void RotateALinkedList(number** head, int node)
{
int count = 0;
number* p = *head;
number* tempNode = NULL;
for (count = 1; ((count < node) && (p != NULL)); count++)
{
p = p->next;
}
if (p == NULL)
{
return;
}
else
{
tempNode = p;
}
while (p->next != NULL)
{
p = p->next;
}
p->next = *head;
*head = tempNode->next;
tempNode->next = NULL;
}
int CreateLinkedList(number** head, int iNumberofNode)
{
int data = 0;
int iRetValue = -1;
int count = 0;
number* pNewNode = NULL;
for (count = 0; count < iNumberofNode; count++)
{
printf("Enter number: ");
scanf("%d", &data);
getchar();
if ((*head) == NULL)
{
pNewNode = (number*)malloc(sizeof(number));
if (pNewNode != NULL)
{
pNewNode->data = data;
pNewNode->next = NULL;
*head = pNewNode;
iRetValue = 0;
}
}
else
{
iRetValue = attachToEnd(head, data);
}
}
return iRetValue;
}
int attachToEnd(number** head, int k)
{
int iRetValue = -1;
number* pLastNode = NULL;
number* pNewNode = NULL;
pLastNode = *head;
pNewNode = (number*)malloc(sizeof(number));
if (pNewNode != NULL)
{
pNewNode->data = k;
pNewNode->next = NULL;
iRetValue = 0;
}
if (pLastNode == NULL)
{
*head = pNewNode;
}
else
{
while (pLastNode->next != NULL)
{
pLastNode = pLastNode->next;
}
pLastNode->next = pNewNode;
}
return iRetValue;
}
void PrintTheList(number* pNode)
{
printf("the rotated list:\n");
while (pNode != NULL)
{
printf("%d ", pNode->data);
pNode = pNode->next;
}
}
void FreeAllocatedMemory(number** head)
{
number* ptempNode = NULL;
number* pFirstNode = NULL;
pFirstNode = *head;
while (pFirstNode != NULL)
{
ptempNode = pFirstNode;
pFirstNode = pFirstNode->next;
free(ptempNode);
}
*head = NULL;
}

For starters the name number of the alias in this typedef declaration
typedef struct numbers_list
{
int data;
struct numbers_list* next;
}number;
is confusing.
It will be better to define two structures instead
struct Node
{
int data;
struct Node *next;
};
struct List
{
size_t size;
struct Node *head;
};
and define in main a list like
struct List numbers = { .size = 0, .head = NULL };
You will simplify your task if the list contains a data member that specifies the number of nodes in the list.
The function CreateLinkedList should do one task: create a list from an array specified by the user. It should ask the user to enter numbers that will be stored in the list.
I can suggest the following solution shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct List
{
size_t size;
struct Node *head;
};
void clear( struct List *list )
{
while ( list->head )
{
struct Node *tmp = list->head;
list->head = list->head->next;
free( tmp );
}
list->size = 0;
}
size_t create( struct List *list, const int a[], size_t n )
{
clear( list );
for ( struct Node **current = &list->head;
n-- && ( *current = malloc( sizeof( struct Node ) ) ) != NULL; )
{
( *current )->data = *a++;
( *current )->next = NULL;
current = &( *current )->next;
++list->size;
}
return list->size;
}
FILE * display( const struct List *list, FILE *fp )
{
fprintf( fp, "There is/are %zu items: ", list->size );
for ( struct Node *current = list->head; current != NULL; current = current->next )
{
fprintf( fp, "%d -> ", current->data );
}
fputs( "null", fp );
return fp;
}
void rotate( struct List *list, size_t n )
{
if ( ( list->size != 0 ) && ( ( n %= list->size ) != 0 ) )
{
struct Node **current = &list->head;
while ( n-- ) current = &( *current )->next;
struct Node *tmp = list->head;
list->head = *current;
*current = NULL;
struct Node *last = list->head;
while ( last->next != NULL ) last = last->next;
last->next = tmp;
}
}
int main(void)
{
struct List numbers = { .size = 0, .head = NULL };
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
create( &numbers, a, sizeof( a ) / sizeof( *a ) );
fputc( '\n', display( &numbers, stdout ) );
rotate( &numbers, 1 );
fputc( '\n', display( &numbers, stdout ) );
rotate( &numbers, 2 );
fputc( '\n', display( &numbers, stdout ) );
rotate( &numbers, 3 );
fputc( '\n', display( &numbers, stdout ) );
rotate( &numbers, 4 );
fputc( '\n', display( &numbers, stdout ) );
clear( &numbers );
return 0;
}
The program output is
There is/are 10 items: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
There is/are 10 items: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 0 -> null
There is/are 10 items: 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 0 -> 1 -> 2 -> null
There is/are 10 items: 6 -> 7 -> 8 -> 9 -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> null
There is/are 10 items: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null

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

Deleting first occurrence in a doubly linked list

I have an assignment to do.. the task is to delete the first odd number only I wrote the code but honestly I have zero confidence about it.. if you guys can help me I would be pleased.
The function deletes the first node that has an odd value, so the function searches for the first node that has an odd value and deletes it.
typedef struct Node {
int data;
struct Node *next;
struct Node *previous;
}Node;
int DeleteFirstODD(Node **front) {
int oddnum;
Node *temp = *front;
if (*front == NULL) //Checking if the list is empty
return;
while (temp != NULL && temp->data % 2 == 0)
temp = temp->next;
if (temp == NULL)
return -1;
else if (temp == *front) { //if odd num founded # the begining of the doubly
linked list!
oddnum = (*front)->data;
*front = (*front)->next;
(*front)->previous = NULL;
free(temp);
}
else if (temp->next == NULL) { //if odd num founded # the end
oddnum = temp->data;
temp->previous->next = NULL;
free(temp);
}
else { // if the odd somewhere in the middle
temp->previous->next = NULL;
temp->next->previous = NULL;
free(temp);
}
return oddnum;
}
For starters this typedef declaration
typedef struct Node {
int data;
Node *next;
Node *previous;
}Node;
is incorrect. You have to write
typedef struct Node {
int data;
struct Node *next;
struct Node *previous;
} Node;
If a function has a return type that is not void then you may not use the return statement without an expression like in your function
return;
The function could return integer value 1 in the case when a node with an odd value was deleted or 0 otherwise.
The code within the function is incorrect. For example this loop
while (ptr != NULL && ptr % 2 != 0) {
oddnum = ptr->data;
ptr = ptr->next;
}
does not make a sense.
The function can be defined the following way
int DeleteFirstODD( Node **front )
{
while ( *front && ( *front )->data % 2 == 0 )
{
front = &( *front )->next;
}
int success = *front != NULL;
if ( success )
{
Node *current = *front;
if ( current->next )
{
current->next->previous = current->previous;
}
*front = current->next;
free( current );
}
return success;
}
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node *next;
struct Node *previous;
} 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;
if ( *head ) ( *head )->previous = new_node;
new_node->previous = NULL;
*head = new_node;
}
return success;
}
void display( const Node *head )
{
for ( ; head; head= head->next )
{
printf( "%d -> ", head->data );
}
puts( "null" );
}
int DeleteFirstODD( Node **front )
{
while ( *front && ( *front )->data % 2 == 0 )
{
front = &( *front )->next;
}
int success = *front != NULL;
if ( success )
{
Node *current = *front;
if ( current->next )
{
current->next->previous = current->previous;
}
*front = current->next;
free( current );
}
return success;
}
int main(void)
{
Node *head = NULL;
const int N = 10;
for ( int i = N; i != 0; i-- )
{
push_front( &head, i );
}
display( head );
while ( DeleteFirstODD( &head ) )
{
display( head );
}
return 0;
}
The program output is
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
2 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
2 -> 4 -> 6 -> 7 -> 8 -> 9 -> 10 -> null
2 -> 4 -> 6 -> 8 -> 9 -> 10 -> null
2 -> 4 -> 6 -> 8 -> 10 -> null

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

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.

Resources