Singly Linked List head of 0 - c

I got problem with Singly Linked List problem.
When i inserted something in front of head. head is always have 0 of data.
I think init_list() function is something wrong. I think head of 0 is from randomly initialized data.
anything is fine without head 0 problem.
I'm sure that initializing method is wrong. But I don't know how to solve it..
Here is my I/0 and Desired Output
Input
2
insert 0 1
size
Output I got
1->0->NULL
2
1->0->NULL
Desired Output
1->NULL
1
1->NULL
Here is My Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int Element;
typedef struct LinkedNode {
Element data;
struct LinkedNode* link;
} Node;
Node* head;
void init_list() {
head = (Node*)malloc(sizeof(Node));
head->link = NULL;
}
int is_empty() {
if (head == NULL) return 1;
else return 0;
}
Node* get_entry(int pos)
{
Node* p = head;
int i;
for (i = 0; i < pos; i++, p=p->link){
if (p == NULL) return NULL;
}
return p;
}
int size()
{
Node* p;
int count = 0;
for (p = head; p != NULL; p = p->link)
count++;
return count;
}
void replace(int pos, Element val)
{
Node* node = get_entry(pos);
if (node != NULL)
node->data = val; // replace
}
Node* search_list(Element val)
{
Node* p;
for (p = head; p != NULL; p = p->link)
if (p->data == val) return p;
return NULL;
}
void insert_next(Node * before, Node * node)
{
if (node != NULL) {
node->link = before->link;
before->link = node;
}
}
void insert(int pos, Element val)
{
Node* new_node, * prev;
new_node = (Node*)malloc(sizeof(Node));
new_node->data = val;
if (pos == 0) {
new_node->link = head;
head = new_node;
}
else {
prev = get_entry(pos-1);
if (prev != NULL)
insert_next(prev, new_node);
else free(new_node);
}
}
Node * remove_next(Node * prev)
{
Node* removed = prev->link;
if (removed != NULL) {
prev->link = removed->link;
}
return removed;
}
void delete(int pos)
{
Node* prev, * removed;
if (pos == 0 && is_empty() == 0) {
removed = get_entry(pos);
head = head->link;
free(removed);
}
else {
prev = get_entry(pos-1);
if (prev != NULL) {
remove_next(prev);
free(removed);
}
}
}
void clear_list()
{
while (is_empty() == 0)
delete(0);
}
void print_list()
{
Node* p;
for (p = head; p != NULL; p = p->link)
printf("%d->", p->data);
printf("NULL\n");
}
Node * concat_list(Node * new_node)
{
if(is_empty()) return new_node;
else if(new_node == NULL) return new_node;
else{
Node* p;
p = head;
while (p->link != NULL) {
p = p->link;
}
p->link = new_node;
return head;
}
}
int main(void)
{
Element num;
int pos;
int n, i, j, len;
char c[15];
Node* tmp_head= NULL;
Node* new_head= NULL;
init_list();
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%s", c);
if (strcmp(c, "insert") == 0) { scanf("%d %d\n",&pos, &num); insert(pos,num); print_list();}
else if (strcmp(c, "delete") == 0) { scanf("%d\n", &pos); delete(pos); print_list();}
else if (strcmp(c, "size") == 0) {printf("%d\n", size()); print_list();}
else if (strcmp(c, "empty") == 0) {printf("%d\n", is_empty()); print_list();}
else if (strcmp(c, "getEntry") == 0) { scanf("%d\n", &pos); printf("%d\n", get_entry(pos)->data); print_list();}
else if (strcmp(c, "search_list") == 0) { scanf("%d\n", &num); printf("%d\n", search_list(num)->data); print_list();}
else if (strcmp(c, "replace") == 0) { scanf("%d %d\n", &pos, &num); replace(pos,num); print_list();}
else if (strcmp(c, "concat_list") == 0) {
tmp_head = head;
init_list();
scanf("%d", &len);
for (j = 0; j < len; j++)
{
scanf("%d %d\n",&pos, &num); insert(pos,num);
}
printf("new_node: ");
print_list();
new_head = head;
head = tmp_head;
head = concat_list(new_head);
print_list();
}
else printf("error\n");
}
return 0;
}

The basic problem is that within init_list, the code only initializes link but not data. I'd suggest instead that you initialize head to NULL and simply use insert to create nodes.

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.

Delete a prime number in a doubly linked list

#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
struct node *prev;
}*head=NULL;
int length(struct node *p)
{
int len;
while(p!=NULL)
{
len++;
p = p->next;
}
return len;
}
void display(struct node *p)
{
if(p == NULL)
{
printf("Linked List is empty\n");
}
else
{
printf("Linked List: ");
while(p!=NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
}
void insert(struct node *p, int index, int x)
{
struct node *t;
if(index == 0)
{
t = (struct node *)malloc(sizeof(struct node));
t->data = x;
t->next = head;
t->prev = NULL;
if(head != NULL)
{
head->prev = t;
}
head = t;
}
else
{
t = (struct node *)malloc(sizeof(struct node));
t->data = x;
for(int i=0; i<index-1; i++)
{
p = p->next;
}
t->prev = p;
t->next = p->next;
if(p->next != NULL)
{
p->next->prev = t;
}
p->next = t;
}
}
int checkprime(int n)
{
int prime = 1;
for(int i=2; i<n; i++)
{
if(n % 2 == 0)
{
prime = 0;
break;
}
}
if(prime == 0)
{
return 0; //It is not a prime number.
}
else
{
return 1; //It is a prime number.
}
}
void delete_prime_number(struct node *p)
{
struct node *q;
while(p != NULL)
{
q = p;
p = p->next;
if((checkprime(q->data)) == 1)
{
free(q);
}
}
}
int main()
{
insert(head, 0, 2);
insert(head, 1, 3);
insert(head, 2, 4);
insert(head, 3, 7);
insert(head, 4, 8);
insert(head, 5, 12);
insert(head, 6, 15);
insert(head, 7, 23);
display(head);
delete_prime_number(head);
display(head);
return 0;
}
This is the code I have tried for this. The problem is in the delete_prime_function. When I run it, it prints random values unlimited times.
I created a checkprime function which will return 1 if the number is prime and return 0 if the number is not prime.
Then in the delete_prime function, each time it would check the condition if((checkprime)==1), and if its true it would delete that node, and the process would go on until pointer "p" reaches NULL.
I'm not getting where I am doing it wrong.
EDIT:
Thank you, I implemented what #pmg and #VladfromMoscow pointed out. Here is the working code.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
struct node *prev;
};
int length(struct node *p)
{
int len = 0;
while (p != NULL)
{
len++;
p = p->next;
}
return len;
}
void display(struct node *p)
{
if (p == NULL)
{
printf("Linked List is empty\n");
}
else
{
printf("Linked List: ");
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
}
void insert(struct node **p, int index, int x)
{
struct node *t;
if (index == 0)
{
t = (struct node *)malloc(sizeof(struct node));
t->data = x;
t->next = *p;
t->prev = NULL;
if ((*p) != NULL)
{
(*p)->prev = t;
}
(*p) = t;
}
else
{
t = (struct node *)malloc(sizeof(struct node));
t->data = x;
for (int i = 0; i < index - 1; i++)
{
if((*p) == NULL)
{
printf("Linked List is empty!\n");
}
else
{
p = &(*p)->next;
}
}
t->prev = (*p);
t->next = (*p)->next;
if ((*p)->next != NULL)
{
(*p)->next->prev = t;
}
(*p)->next = t;
}
}
int checkprime(int n)
{
int prime = 1;
if(n == 0 || n == 1)
{
return 0;
}
else
{
for (int i = 2; i < n; i++)
{
if (n % i == 0)
{
prime = 0;
break;
}
}
if (prime == 0)
{
return 0; //It is not a prime number.
}
else
{
return 1; //It is a prime number.
}
}
}
void delete_prime_number(struct node **p)
{
while (*p != NULL)
{
if (checkprime((*p)->data) == 1)
{
struct node *q = *p;
if ((*p)->next != NULL)
{
(*p)->next->prev = (*p)->prev;
}
*p = (*p)->next;
free(q);
}
else
{
p = &(*p)->next;
}
}
}
int main()
{
struct node *head = NULL;
insert(&head, 0, 2);
insert(&head, 1, 3);
insert(&head, 2, 4);
insert(&head, 3, 7);
insert(&head, 4, 8);
insert(&head, 5, 12);
insert(&head, 6, 15);
insert(&head, 7, 23);
display(head);
delete_prime_number(&head);
printf("\n");
display(head);
return 0;
}
Thanks again :)
Imagine this 3 nodes list:
NULL==p /<==p /<==p
NODE NODE NODE
n==>/ n==>/ n==NULL
When you remove the 2nd node in this list you want to get
NULL==p /<==========p // changed prev link in 3rd node
NODE ---- NODE // deleted 2nd node
n==========>/ n==NULL // changed next link in 1st node
But your code is getting this
NULL==p ---- /<==p // prev links to deleted node
NODE ---- NODE
n==>/ ---- n==NULL // next links to deleted node
Beware the special cases of the first and last nodes in the list.
Your implementation of the list is incorrect and many functions can invoke undefined behavior.
For starters the functions shall not rely on the global variable head. In this case a program for example can not use two lists simultaneously.
The function length invokes undefined behavior because the local variable len is not initialized.
int length(struct node *p)
{
int len;
while(p!=NULL)
{
len++;
p = p->next;
}
return len;
}
You need to write
int len = 0;
In the function insert in this code snippet
for(int i=0; i<index-1; i++)
{
p = p->next;
}
t->prev = p;
t->next = p->next;
if(p->next != NULL)
{
p->next->prev = t;
}
p->next = t;
you do not check whether p is equal to NULL. For example if the list is empty that is head is a null pointer and the user specified index equal to 1 then p also will be a null pointer. So using it in expressions like for example this p->next invokes undefined behavior.
The function checkprime is also incorrect. It shows that numbers 0, 1 and all odd numbers are prime numbers due to the if statement
if(n % 2 == 0)
{
prime = 0;
break;
}
that will not get the control for such numbers.
So at first you have to write the list (declaring head as a local variable) and all the mentioned functions correctly before writing the function delete_prime_number which naturally also incorrect because at least it does not change the pointer head when the pointed node contains a prime number.
As for the function delete_prime_number itself then it can be defined the following wat
void delete_prime_number( struct node **head )
{
while ( *head != NULL )
{
if ( checkprime( ( *head )->data ) )
{
struct node *tmp = *head;
if ( ( *head )->next != NULL )
{
( *head )->next->prev = ( *head )->prev;
}
*head = ( *head )->next;
free( tmp );
}
else
{
head = &( *head )->next;
}
}
}
and can be called like
delete_prime_number( &head );

Circular Doubly Linked List- Delete node

I am working on building circular doubly linked list code.
In my code, there are four function- add node, delete node, print clockwise, print counterclockwise. All my code works fine, besides the delete function. The if(recycle->name == x) line seems not working properly, and free(recycle) also doesn't successfully free the recycle node.
My original code are. as follows
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define nameLen 20
struct Node
{
char name[nameLen];
struct Node *left; //next
struct Node *right; //previous
};
struct Node* current;
struct Node* head;
int count = 0;
struct Node* GetNewNode(char *x)
{
struct Node* newNode;
newNode = (struct Node*)malloc(sizeof(struct Node));
strncpy(newNode->name, x, nameLen);
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
void add_name(char *x)
{
struct Node* temp = current;
struct Node* newNode = GetNewNode(x);
count++;
if(current == NULL)
{
current = newNode;
head = current;
}
else
{
current->left = newNode;
newNode->right = temp;
current = newNode;
current->left = head;
head->right = current;
}
printf("Add %s into database.\n\n", current->name);
}
void delete_name(char *x)
{
int i, j;
struct Node* recycle = current;
if(current == NULL)
{
printf("No data input.");
}
else
{
for (i = 0; i < count; i++)
{
if(recycle->name == x)
{
free(recycle);
j++;
printf("Delete %s from database.\n", x);
}
recycle = recycle->left;
}
if(j == 0)
{
printf("There is no %s in data", x);
}
current = recycle;
}
}
void print_clock(int number)
{
int i;
struct Node* temp = current;
if(temp == NULL)
{
printf("No data input.");
}
else
{
printf("Clockwise: \n");
for(i = 0; i < number; i++)
{
printf("%s ",temp->name);
temp = temp->left;
}
}
printf("\n\n");
}
void print_counter(int number)
{
int i;
struct Node* temp = current;
if(temp == NULL)
{
printf("No data input.");
}
else
{
printf("Counterclockwise: \n");
for(i = 0; i < number; i++)
{
printf("%s ",temp->name);
temp = temp->right;
}
}
printf("\n\n");
}
int main()
{
char s1;
char s2[nameLen];
char name[nameLen];
int number;
while(1)
{
printf("Enter the instruction: ");
scanf("%s %s", &s1, s2);
if (s1 == '+' && sscanf(s2, "%d", &number) == 1)
{
printf("Print out %d name(s) clockwise.\n", number);
print_clock(number);
}
else if (s1 == '-' && sscanf(s2, "%d", &number) == 1)
{
printf("Print out %d name(s) counterclockwise.\n", number);
print_counter(number);
}
else if (s1 == '+' && sscanf(s2, "%s", name) == 1)
{
add_name(s2);
}
else if (s1 == '-' && sscanf(s2, "%s", name) == 1)
{
delete_name(s2);
}
else if (s1 == 'e')
{
printf("Bye.\n");
break;
}
else // No match.
printf("Wrong Input. %s %s\n", &s1, s2);
}
system("pause");
return 0;
}
Statement recycle->name == x checks if two pointers point to the same object in memory. It does not check if two (different) objects in memory have equal content.
Use
if (strcmp(recycle->name, x) == 0) { ...
to check for equal string contents.

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.

LinkedList with Char (String Issue

So I'm having issue with my code with the structure I'm using. I would like my structure to be able add,retrieve or sort but I'm getting a lot of problem with the structure. It work if I use only number but I need to user 3 string. One for firstname, lastname and phonenumber but I can't figure.
This is the code I'm having right now:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
char first[15];
char last[15];
char phone[12];
struct node *next;
}*head;
void append(int num, char f[15], char l[15],char p[12])
{
struct node *temp, *right;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = num;
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);
right = (struct node *)head;
while (right->next != NULL)
right = right->next;
right->next = temp;
right = temp;
right->next = NULL;
}
void add(int num, char f[15], char l[15],char p[12])
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = num;
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);
if (head == NULL)
{
head = temp;
head->next = NULL;
}
else
{
temp->next = head;
head = temp;
}
}
void addafter(int num, char f[15], char l[15],char p[12],int loc)
{
int i;
struct node *temp, *left, *right;
right = head;
for (i = 1; i<loc; i++)
{
left = right;
right = right->next;
}
temp = (struct node *)malloc(sizeof(struct node));
temp->data = num;
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);
left->next = temp;
left = temp;
left->next = right;
return;
}
void insert(int num, char f[15], char l[15],char p[12])
{
int c = 0;
struct node *temp;
temp = head;
if (temp == NULL)
{
add(num,f,l,p);
}
else
{
while (temp != NULL)
{
if (temp->data<num)
c++;
temp = temp->next;
}
if (c == 0)
add(num,f,l,p);
else if (c<count())
addafter(num,f,l,p, ++c);
else
append(num,f,l,p);
}
}
int delete(int num)
{
struct node *temp, *prev;
temp = head;
while (temp != NULL)
{
if (temp->data == num)
{
if (temp == head)
{
head = temp->next;
free(temp);
return 1;
}
else
{
prev->next = temp->next;
free(temp);
return 1;
}
}
else
{
prev = temp;
temp = temp->next;
}
}
return 0;
}
void display(struct node *r)
{
r = head;
if (r == NULL)
{
return;
}
while (r != NULL)
{
printf("%d ", r->data);
r = r->next;
}
printf("\n");
}
int count()
{
struct node *n;
int c = 0;
n = head;
while (n != NULL)
{
n = n->next;
c++;
}
return c;
}
int main()
{
int i, num;
char fname[15], lname[15], phone[12];
struct node *n;
head = NULL;
while (1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Retrieve\n");
printf("4.Delete\n");
printf("5.Exit\n");
printf("Enter your choice : ");
if (scanf("%d", &i) <= 0){
printf("Enter only an Integer\n");
exit(0);
}
else {
switch (i)
{
case 1:
printf("Enter the id, first, last and phone (Separte with space) : ");
scanf("%d %s %s %s", &num,fname,lname,phone);
insert(num,fname,lname,phone);
break;
case 2:
if (head == NULL){
printf("List is Empty\n");
}else{
printf("Element(s) in the list are : ");
}
display(n);
break;
case 3:
//To be made
//scanf("Retrieve this : %d\n", count());
break;
case 4:
if (head == NULL){
printf("List is Empty\n");
}else{
printf("Enter the number to delete : ");
scanf("%d", &num);
if (delete(num))
printf("%d deleted successfully\n", num);
else
printf("%d not found in the list\n", num);
}
break;
case 5:
return 0;
default:
printf("Invalid option\n");
}
}
}
return 0;
}
Thanks for anyone that could explain me the issue and or fix it.
Everywhere you have:
temp->data = num;
add the lines
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);

Resources