Function the separates even and odd numbers using linked list - c

I am trying, to get a number from a user and create 2 linked lists, one with only even numbers, the other one with odd numbers, I have to return the number of total numbers have been inserted, and pass by reference the linked-lists.
my main issue is with the return of the 2 new linked lists, here is what I have done so far. I get an error
Error C2440 'function': cannot convert from 'node **' to 'node'.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}node;
struct node* head;
int get_values(node,node);
void main() {
node *even_node,*odd_node;
get_values(&even_node,&odd_node);
}
int get_values(node *even, node *odd) {
int value, counter_total = 0;
node *curr_even;
node *curr_odd;
head = NULL;
printf("enter value:");
scanf_s("%d", &value);
if (value == -1) {
return NULL;
}
if (value % 2 == 0) {
even = (node*)malloc(sizeof(node));
curr_even = even;
even->data = value;
counter_total++;
}
else {
odd = (node*)malloc(sizeof(node));
curr_odd = odd;
odd->data = value;
counter_total++;
}
//2nd and on insertion.
while (value != -1) {
printf("enter a value positive value");
scanf_s("%d", &value);
if (value == -1) {
curr_even->next = NULL;
curr_odd->next = NULL;
break;
}
else if (value % 2 == 0) {
curr_even->next = (node *)malloc(sizeof(node));
curr_even = curr_even->next;
curr_even->data = value;//current value
counter_total++;
}
else {
curr_odd->next = (node*)malloc(sizeof(node));
curr_odd = curr_odd->next;
curr_odd->data = value; //current value
counter_total++;
}
return counter_total;
}
}

There are quite a few things wrong with your code.
The function definition for getvalues should have a double pointer.
In the function, you are malloc ing at the function parameters. While you need to malloc a local variable and add it to the list.
You are adding an unnecessary code duplication when a single do while loop is sufficient.
See the fixed code below
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node *next;
}node;
struct node* head;
int get_values(node **,node **);
void main() {
node *even_node= NULL,*odd_node= NULL;
get_values(&even_node,&odd_node);
}
int get_values(node **even, node **odd) {
int value, counter_total = 0;
node *curr_even;
node *curr_odd;
node *new_node;
do
{
printf("enter value:");
scanf("%d", &value);
if (value == -1) {
return counter_total;
}
if (value % 2 == 0)
{
new_node = (node*)malloc(sizeof(node));
new_node -> data = value;
new_node -> next = NULL;
if (*even == NULL)
{
*even = new_node;
curr_even = *even;
}
else
{
curr_even ->next = new_node;
curr_even = curr_even -> next;
}
counter_total++;
}
else
{
new_node = (node*)malloc(sizeof(node));
new_node -> data = value;
new_node -> next = NULL;
if (*even == NULL)
{
*even = new_node;
curr_even = *even;
}
else
{
curr_even ->next = new_node;
curr_even = curr_even -> next;
}
counter_total++;
}
}while (1);
}

If you want to have pass by reference you can do it as below.
int get_values(node **even, node **odd) {
int value, counter_total = 0;
printf("enter value:");
scanf_s("%d", &value);
while (value != -1) {
if (value % 2 == 0) {
while(*even != NULL) even= &(*even)->next; //Move the pointer till last node.
*even = (node *)malloc(sizeof(node));
(*even)->data = value;//current value
(*even)->next = NULL;
counter_total++;
}
else {
while(*odd != NULL) odd= &(*odd)->next;
*odd = (node *)malloc(sizeof(node));
(*odd)->data = value;//current value
(*odd)->next = NULL;
counter_total++;
}
printf("enter a value positive value");
scanf_s("%d", &value);
}
return counter_total;
}

Related

delete the biggest number in linked list from anywhere (in C)

I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node
{
int x;
struct Node *next;
} Node;
void deallocate(Node **root)
{
Node *curr = *root;
while (curr != NULL)
{
Node *aux = curr;
curr = curr->next;
free(aux);
}
*root = NULL;
}
void insert_end(Node **root, int value)
{
Node *new_node = malloc(sizeof(Node));
if (new_node == NULL)
{
exit(1);
}
new_node->next = NULL;
new_node->x = value;
if (*root == NULL)
{
*root = new_node;
return;
}
Node *curr = *root;
while (curr->next != NULL)
{
curr = curr->next;
}
curr->next = new_node;
}
void deserialize(Node **root)
{
FILE *file = fopen("duom.txt", "r");
if (file == NULL)
{
exit(2);
}
int val;
while (fscanf(file, "%d, ", &val) > 0)
{
insert_end(root, val);
}
fclose(file);
}
int largestElement(struct Node *root)
{
int max = INT_MIN;
while (root != NULL)
{
if (max < root->x)
max = root->x;
root = root->next;
}
return max;
}
void deleteN(Node **head, int position)
{
Node *temp;
Node *prev;
temp = *head;
prev = *head;
for (int i = 0; i < position; i++)
{
if (i == 0 && position == 1)
{
*head = (*head)->next;
free(temp);
}
else
{
if (i == position - 1 && temp)
{
prev->next = temp->next;
free(temp);
}
else
{
prev = temp;
// Position was greater than
// number of nodes in the list
if (prev == NULL)
break;
temp = temp->next;
}
}
}
}
int main()
{
Node *root = NULL;
printf("MENU:\n");
printf("if you press 0 the list will be created \n");
printf("if you press 1 the list will be printed on a screen\n");
printf("if you press 2 it deletes the biggest element\n");
printf("if you press 3 the program ends\n\n");
int meniu;
printf("press:\n");
scanf("%d", &meniu);
while (meniu != 3)
{
if (meniu == 0)
{
deserialize(&root);
printf("sarasas sukurtas.\n");
}
if (meniu == 1)
{
for (Node *curr = root; curr != NULL; curr = curr->next)
printf("%d\n", curr->x);
}
if (meniu == 2)
{
int max_element = largestElement(root);
printf("%d max\n", max_element);
deleteN(&root, max_element);
}
printf("press:\n");
scanf("%d", &meniu);
}
deallocate(&root);
return 0;
}
When I compile and run the delete function it only deletes the biggest number first time and if I call it second time it deletes the last number of the list. Can someone help me fix that?
I edited it so all of the code can be seen because it was hard to understand it like I had it before
Your largestElement returns the largest data value in the list.
However, here:
int max_element = largestElement(root);
printf("%d max\n",max_element);
deleteN(&root, max_element);
you use the return value as if it is the position of the node with the largest element.
Instead of largestElement you need a function that returns the position of the element with the largest data value.
It would look something like:
int positionOfLargestElement(struct Node* root)
{
int pos = 0;
int maxpos = 0;
int max = INT_MIN;
while (root != NULL) {
++pos;
if (max < root->x)
{
max = root->x;
maxpos = pos;
}
root = root->next;
}
return maxpos;
}
note: The exact code depends a bit on whether the first node is considered to be position 0 or position 1 but the principle is the same.

C - Linked list program giving the error "Return value ignored: 'scanf'". Also please point out if you find any other mistakes

I am trying to write a code to implement a linked list. The program inserts a value taken from the user into a linked list until the user exits execution. The value can be inserted into the head, tail or any custom position entered by the user.
Upon compiling the program gives the error "Return value ignored: 'scanf'" on every scanf. It also gave an error saying scanf is unsafe, use scanf_s instead. I resolved that by adding '_CRT_SECURE_NO_WARNINGS' to preprocessor definitions. Also please point out if you find any other mistakes.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node* next;
} node;
typedef enum position { First = 1, Custom, Last} position;
typedef enum process {Exit, Run} process;
node* insertFirst(node* ptrHead, int val)
{
node* temp = NULL;
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
exit(1);
}
else
{
if (ptrHead == NULL)
{
newNode->data = val;
newNode->next = NULL;
ptrHead = newNode;
}
else
{
temp = ptrHead;
newNode->data = val;
newNode->next = temp;
ptrHead = newNode;
}
}
return ptrHead;
}
node* insertPos(node* ptrHead, int val, int loc)
{
node* temp = ptrHead;
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
exit(1);
}
for (int i = 0; i < loc; i++)
{
temp = temp->next;
}
newNode->data = val;
newNode->next = temp->next;
temp->next = newNode;
return ptrHead;
}
node* insertLast(node* ptrHead, int val)
{
node* temp = ptrHead;
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
exit(1);
}
newNode->data = val;
newNode->next = NULL;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newNode;
return ptrHead;
}
void printList(node* ptrHead)
{
node* temp = ptrHead;
while (temp->next != NULL)
{
printf("%d\n", temp->data);
temp = temp->next;
}
}
int countNodes(node* ptrHead)
{
node* temp = ptrHead;
int i = 0;
while (temp->next != NULL)
{
temp = temp->next;
i++;
}
return i;
}
int main()
{
node* ptrHead = NULL;
position location;
int num = 0;
int pos = 0;
process state = Run;
while (state == Run)
{
printf(" Welcome to my Linked List program. \n");
if (ptrHead == NULL)
{
printf("Enter first element of the list \n");
scanf("%d", &num);
ptrHead = insertFirst(ptrHead, num);
}
else
{
printf(" Enter number to choose location: \n 1 -> First\n 2-> Custom\n 3-> Last\n");
scanf("%d", &pos);
if (pos == Custom)
{
printf("Please enter the number and the placement\n");
scanf("%d", &num);
scanf("%d", &location);
if (location > countNodes(ptrHead))
{
printf("Enter position less than %d\n", countNodes(ptrHead));
}
else
{
ptrHead = insertPos(ptrHead, num, location);
}
}
else if (pos == First)
{
printf("Please enter the number\n");
scanf("%d", &num);
ptrHead = insertFirst(ptrHead, num);
}
else if (pos == Last)
{
printf("Please enter the number\n");
scanf("%d", &num);
ptrHead = insertLast(ptrHead, num);
}
else
{
printf("Wrong position entry\n");
}
}
printList(ptrHead);
printf("Enter '1' to insert another value and '0' to quit execution\n");
scanf("%d", &state);
}
return 0;
}

How to prevent the program to display the converted input, I'm wanting the program to display the original input

I want my code to display the original input 3 -> 2-> 1-> and not display the reversed one.
The output is displaying the 1-> 2-> 3-> . I want to see the original input without ruining the codes. How can I do that? Our professor taught us the concept of linked list and it is connected in this program to input a number and check if it is a palendrome
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
void insertNum(struct node** head, int number) {
struct node* temp = malloc(sizeof(struct node));
temp -> data = number;
temp -> next = *head;
*head = temp;
}
void display(struct node* head) {
struct node* printNode = head;
printf("displaying list1...\n");
printf("displaying the converted list..\n");
while (printNode != NULL) {
if (printNode->next)
printf("%d->",printNode->data);
else
printf("%d->NULL\n",printNode->data);
printNode=printNode->next;
}
}
struct node* reverseLL(struct node* head) {
struct node* reverseNode = NULL, *temp;
if (head == NULL) {
printf("\nThe list is empty.\n\n");
exit(0);
}
while (head != NULL) {
temp = (struct node*) malloc(sizeof(struct node));
temp -> data = head -> data;
temp -> next = reverseNode;
reverseNode = temp;
head = head -> next;
}
return reverseNode;
}
int check(struct node* LLOne, struct node* LLTwo) {
while (LLOne != NULL && LLTwo != NULL) {
if (LLOne->data != LLTwo->data)
return 0;
LLOne = LLOne->next;
LLTwo = LLTwo->next;
}
return (LLOne == NULL && LLTwo == NULL);
}
void deleteList(struct node** display) {
struct node* temp = *display;
while (temp != NULL) {
temp = temp->next;
free(*display);
*display = temp;
}
}
int main() {
int inputNum, countRun = 0, loop;
char choice;
struct node* reverseList;
struct node* head = NULL;
do {
printf("%Run number : %d\n", ++countRun);
printf("Enter 0 to stop building the list, else enter any integer\n");
printf("Enter list to check whether it is a palindrome... \n");
do {
scanf("%d", &inputNum);
if (inputNum == 0)
break;
insertNum(&head, inputNum);
} while (inputNum != 0);
display(head);
reverseList = reverseLL(head);
if ((check(head, reverseList)) == 1)
printf("\nPalindrome list.\n\n");
else
printf("\nNot palindrome.\n\n");
deleteList(&head);
} while (countRun != 2);
system("pause");
return 0;
}
Your insertNum inserts at the front of the list.
You need a version that appends at the back of the list:
void
appendNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
struct node *cur;
struct node *prev;
temp->data = number;
// find tail of the list
prev = NULL;
for (cur = *head; cur != NULL; cur = cur->next)
prev = cur;
// append after the tail
if (prev != NULL)
prev->next = temp;
// insert at front (first time only)
else
*head = temp;
}
Here is the full code:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
void
appendNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
struct node *cur;
struct node *prev;
temp->data = number;
// find tail of the list
prev = NULL;
for (cur = *head; cur != NULL; cur = cur->next)
prev = cur;
// append after the tail
if (prev != NULL)
prev->next = temp;
// insert at front (first time only)
else
*head = temp;
}
void
insertNum(struct node **head, int number)
{
struct node *temp = malloc(sizeof(struct node));
temp->data = number;
temp->next = *head;
*head = temp;
}
void
display(struct node *head)
{
struct node *printNode = head;
printf("displaying list1...\n");
printf("displaying the converted list..\n");
while (printNode != NULL) {
if (printNode->next)
printf("%d->", printNode->data);
else
printf("%d->NULL\n", printNode->data);
printNode = printNode->next;
}
}
struct node *
reverseLL(struct node *head)
{
struct node *reverseNode = NULL,
*temp;
if (head == NULL) {
printf("\nThe list is empty.\n\n");
exit(0);
}
while (head != NULL) {
temp = (struct node *) malloc(sizeof(struct node));
temp->data = head->data;
temp->next = reverseNode;
reverseNode = temp;
head = head->next;
}
return reverseNode;
}
int
check(struct node *LLOne, struct node *LLTwo)
{
while (LLOne != NULL && LLTwo != NULL) {
if (LLOne->data != LLTwo->data)
return 0;
LLOne = LLOne->next;
LLTwo = LLTwo->next;
}
return (LLOne == NULL && LLTwo == NULL);
}
void
deleteList(struct node **display)
{
struct node *temp = *display;
while (temp != NULL) {
temp = temp->next;
free(*display);
*display = temp;
}
}
int
main()
{
int inputNum, countRun = 0, loop;
char choice;
struct node *reverseList;
struct node *head = NULL;
do {
printf("%Run number : %d\n", ++countRun);
printf("Enter 0 to stop building the list, else enter any integer\n");
printf("Enter list to check whether it is a palindrome... \n");
do {
scanf("%d", &inputNum);
if (inputNum == 0)
break;
#if 0
insertNum(&head, inputNum);
#else
appendNum(&head, inputNum);
#endif
} while (inputNum != 0);
display(head);
reverseList = reverseLL(head);
if ((check(head, reverseList)) == 1)
printf("\nPalindrome list.\n\n");
else
printf("\nNot palindrome.\n\n");
deleteList(&head);
} while (countRun != 2);
system("pause");
return 0;
}

Not getting the changed linked list after changing

I made a linked-list and returned by reference, for some reason after sending it to another function it does not getting back with changes unless I send it again by reference, any explanation why?
if I just send "lst" to the function as lst without the "&" when it comes back from the function I only get an odd list,When I used the debugger inside the function I saw the list the with the even values(which should be also in the main),as I think it should be like that since lst is the base address like an array,or am I wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
}node;
node* get_lst(node **linked_lst);
node *createList2(node** L);
void main() {
node *odd_node = NULL, *lst = NULL;
get_lst(&lst);//get values for the original list
odd_node = createList2(&lst);//get an odd list
getch();
}
node *createList2(node **L)
{
node * tList = *L, odd_lst;
node *temp_odd = &odd_lst;
temp_odd->next = NULL;
//first element in the list is odd
while (tList != NULL && tList->data % 2)
{
temp_odd->next = tList;
tList = tList->next;
*L = tList;
temp_odd = temp_odd->next;
temp_odd->next = NULL;
}
//first element in the list is even
while (tList != NULL)
{
if (tList->next != NULL && tList->next->data % 2)
{
temp_odd->next = tList->next;
tList->next = tList->next->next;
temp_odd = temp_odd->next;
temp_odd->next = NULL;
}
else
tList = tList->next;
}
return odd_lst.next;
}
node* get_lst(node **linked_lst) {
int value;
node *curr = NULL;
node *new_node;
do
{
printf("enter value:");
scanf_s("%d", &value);
if (value <0) {
return NULL;
}
new_node = (node*)malloc(sizeof(node));
new_node->data = value;
new_node->next = NULL;
if (*linked_lst == NULL)
{
*linked_lst = new_node;
curr = *linked_lst;
}
else
{
curr->next = new_node;
curr = curr->next;
}
} while (value >= 0);
return *linked_lst;
}

delete element from a list

#include <stdio.h>
#include <malloc.h>
struct el {
int info;
struct el* next;
};
struct el* create_el(struct el* Li)
{
int num;
printf("\n\nInsert number:\n\n");
scanf("%d", &num);
Li = (struct el*)malloc(sizeof(struct el));
if (Li != NULL) {
Li->info = num;
Li->next = NULL;
}
return (Li);
}
struct el* push(struct el* L, struct el* e)
{ //inserts the elements from the head of the list
if (L == NULL)
return (e);
else {
e->next = L;
L = e;
return (L);
}
}
void visualize(struct el* primo)
{
printf("\n\nList-->");
while (primo->next != NULL) {
printf("%d", primo->info);
printf("-->");
primo = primo->next;
}
if (primo->next == NULL)
printf("%d-->NULL", primo->info);
}
struct el* cancel(struct el** P, int val)
{ //delete element
struct el* prec = NULL;
struct el* curr = (*P);
if (P == NULL) //case empty list
return NULL;
else if (prec == NULL) {
if (curr->info == val) { //case 2 : if the element is the head
(*P)->next = curr->next;
free(curr);
curr = NULL;
}
}
else {
while ((curr != NULL) && (curr->info != val)) {
prec = curr;
curr = curr->next;
}
if (curr->next == NULL && curr->info == val) { // case 3: the elemnt is the last one
prec->next = NULL;
free(curr);
curr = NULL;
return (prec);
}
else {
if (curr->info == val) { //other cases
prec->next = curr->next;
free(curr);
curr = NULL;
return (prec);
}
}
}
}
int main()
{
struct el* head = NULL;
struct el* element;
struct el* list = NULL;
int i, n;
int elem;
printf("Insert the number of elements for the list:\n\n");
scanf("%d", &n);
for (i = 0; i <= n; i++) {
element = create_el(head);
if (element != NULL) {
list = push(list, element);
}
}
visualize(list);
printf("\n\nInsert the element that you want to cancel:");
elem = scanf("%d", &elem);
cancel(&list, elem);
visualize(list);
}
All I've wanted to do was delete an element from a listr, but after all the procediment the list is printed without any modification.
Can anyone see whats wrong in the function cancel(which is meant to delete an element by including any possible position of it)?
In your function cancel, P is definitely not NULL (assuming OS has assigned it an address initially).
prec is NULL the before execution enters if loop.
So, execution executes the line
if(curr->info==val)
Now, if the value, val, you have provided doesn't match curr->info then execution exits the function without deleting any node.

Resources