Insertion into linked list - c

I wrote a program that inserts nodes into a linked list in descending order.But whenever I test my code with numbers 12,14,13,19,7 in this order.Whenever I entered 7 I took 7 is already in the list.But as easily seen 7 is not in the list before I inserted.After give this error,if I choose print option by typing 2 my program entered in an infinite loop.I can not see my mistake and I am very confused.
#include <stdio.h>
#include <stdlib.h>
struct node {
int content;
struct node* nextLink;
};
typedef struct node NODE;
void print (NODE*);
int insertNode (NODE** head, int x);
int main (void)
{
int num, choice;
NODE* head;
head = NULL;
do {
printf("\nPlease press 1 to insert or press 2 to print or press 0 to exit\n");
scanf("%d", &choice);
switch (choice) {
case 0:
return 0;
break;
case 1:
printf("Enter an integer to insert into the linkedlist: ");
printf("\n");
scanf("%d", &num);
insertNode(&head, num);
break;
case 2:
print(head);
break;
default:
printf("You entered an invalid number\n");
return 0;
break;
}
} while (choice == 1 || choice == 2);
return 0;
}
int insertNode (NODE** head, int i)
{
NODE* newNode;
newNode = (NODE*)malloc(sizeof(NODE));
newNode->content = i;
NODE* temporary = *head;
newNode->nextLink = NULL;
if ((*head == NULL) || ((*head)->content) < i) {
*head = newNode;
(*head)->nextLink = temporary;
}
else {
do {
if (((temporary->content) > i) && ((temporary->nextLink->content) < i)) {
newNode->nextLink = temporary->nextLink;
temporary->nextLink = newNode;
return;
}
else if (temporary->content == i) {
printf("To be inserted value is already in the list\n");
return;
}
temporary = temporary->nextLink;
} while (temporary->nextLink != NULL);
if (temporary->content == i) {
printf("To be inserted value is already in the list\n");
return;
}
temporary->nextLink = newNode;
}
return 0;
}
void print (NODE* head)
{
if (head == NULL) {
printf("\nLinkedList is empty \n");
}
while (head != NULL) {
printf("%d ", head->content);
head = head->nextLink;
}
}

I compiled it and ran it and it seemed to work fine except for one thing. insertNode is defined to return an int, yet 3 of the return statements are void returns. To get it to compile, I changed them to return 0;. If you were able to compile and run it as is, then it could be the stack was getting destroyed by the inconsistent returns.

Your code won't work, if the first two values to be inserted are in descending order. It would give segmentation fault.
For the insertion of 2nd element you need to be careful
So after if condition
else if (temporary->content > i && temporary->nextLink==NULL)
(*head)->nextLink = newNode;

Your code is doing too much. If you code it differently, there are no special cases (such as insert at the top, insert at the tail of the list).
int insertNode (NODE **head, int val)
{
NODE *newnode;
for ( ; *head; head = &(*head)->nextLink) {
if ( (*head)->content == val) {
printf("To be inserted value (%d)is already in the list\n", val);
return 0;
}
if ( (*head)->content > val) break;
}
newnode = malloc(sizeof *newnode); // Maybe check return here ;-)
newnode->content = val;
newnode->nextLink = *head;
*head = newnode;
return 1;
}

Related

Why is function exiting if the initial input is -1?

#include <stdio.h>
#include <stdlib.h>
/*EVERYTHING WORKS EXCEPT FOR INITIAL -1*/
// Implementing a Node Structure - This represents a node of data
typedef struct _listnode
{
int item; // Data
struct _listnode *next; // Linkage
} ListNode;
// Core Functions of a Linked List
void printList(ListNode *head);
ListNode* findNode(ListNode *head, int index);
int insertNode(ListNode **ptrHead, int index, int value);
void removeNode(ListNode **ptrHead, int index);
int main()
{
// Instantiate a Linked List
ListNode *head = NULL, *temp;
/*
head is a pointer variable that will eventually point to the firstNode.
temp is a pointer variable that points to the lastNode. This is used in from Linked List functions.
*/
int num_to_store;
printf("Enter an Integer to Store (-1 to end):\n");
scanf("%d", &num_to_store);
while (num_to_store != -1)
{
// Initialize a Linked List
if (head == NULL)
{
head = malloc(sizeof(ListNode));
temp = head;
}
else
{
temp->next = malloc(sizeof(ListNode));
temp = temp->next;
}
temp->item = num_to_store;
printf("Enter an Integer to Store (-1 to end):\n");
scanf("%d", &num_to_store);
}
temp->next = NULL;
// Menu-Driven Application
int user_choice, index, value, *p, option_3;
puts("");
printf("----------------\n 1: printList()\n 2: findNode()\n 3: insertNode()\n 4: removeNode()\n-1: End\n----------------\n");
scanf("%d", &user_choice);
while (user_choice != -1)
{
switch(user_choice)
{
case 1:
printList(head);
break;
case 2:
printf("Enter index to search:\n");
scanf("%d", &index);
p = findNode(head, index);
if (p != NULL) printf("Node Item: %d\n", *p);
break;
case 3:
printf("Enter index to insert:\n");
scanf("%d", &index);
printf("Enter value to insert:\n");
scanf("%d", &value);
option_3 = insertNode(&head, index, value);
if (option_3 == 0) printf("NODE INSERTED!\n");
break;
case 4:
printf("Enter index to remove:\n");
scanf("%d", &index);
removeNode(&head, index);
break;
}
// Prompt User to Make Another Selection
puts("");
printf("----------------\n 1: printList()\n 2: findNode()\n 3: insertNode()\n 4: removeNode()\n-1: End\n----------------\n");
scanf("%d", &user_choice);
}
return 0;
}
void printList(ListNode *head)
{
// Linked List is Empty
if (head == NULL)
{
printf("LINKED LIST IS EMPTY!\n");
}
// Linked List is Not Empty
else
{
printf("LINKED LIST: ");
while (head != NULL)
{
printf("%d ", head->item);
head = head->next;
}
puts("");
}
}
ListNode* findNode(ListNode *head, int index)
{
// Linked List is Empty or Index is Invalid
if (head == NULL || index < 0)
{
printf("INVALID!\n");
return NULL;
}
// Linked List is not Empty, Check if Index > len(Linked List)
else
{
while (index > 0)
{
head = head->next;
if (head == NULL)
{
printf("INVALID!\n");
return NULL;
}
index--;
}
printf("INDEX FOUND!\n");
return head;
}
}
int insertNode(ListNode **ptrHead, int index, int value)
{
ListNode *cur, *pre;
// Linked List is Empty || Insert at Index 0
if ((*ptrHead) == NULL || index == 0)
{
cur = *ptrHead;
*ptrHead = malloc(sizeof(ListNode));
(*ptrHead)->item = value;
(*ptrHead)->next = cur;
return 0;
}
// Insert in the Middle
else
{
pre = findNode(*ptrHead, index-1);
if (pre != NULL)
{
cur = pre->next; // This is temporary
pre->next = malloc(sizeof(ListNode)); // L connects to nN
pre->next->item = value;
pre->next->next = cur; // nN connects to R
}
return 0;
}
return -1;
}
void removeNode(ListNode **ptrHead, int index)
{
ListNode *cur, *pre;
// Linked List is Empty
if ((*ptrHead == 0) || index < 0)
{
printf("INVALID!\n");
}
// Remove firstNode
else if (index == 0)
{
cur = findNode(*ptrHead, index);
*ptrHead = cur->next;
free(cur); // Unallocate the memory
}
// Remove Middle
else
{
pre = findNode(*ptrHead, index-1);
cur = findNode(*ptrHead, index);
pre->next = cur->next;
cur->next = NULL;
}
}
Hi all, I am writing a Linked List program in C with the 4 core functions. The functions and everything else works except for when I compile the code and type -1. The program exits. I wonder what is wrong. I tried debugging on code::blocks but nothing showed up.
What am I trying to achieve?
Create a Linked List with no nodes.
Code the 4 core functions of a Linked List (insert/remove/print/search).
What have I tried?
Scattering printf() statements to debug.
Checked on stackoverflow for similar problems.
Viewed the code on geeksforgeeks.
Any idea the cause of the problem might be? And any possible solutions for this type of problem?
When you type -1, the whole while (num_to_store != -1) loop will be skipped, and temp will remain uninitialized, that will make temp->next = NULL; invoke undefined behavior.

Unable to create a linked list in Linux using C

I have written a similar piece of code in C++ for Windows where I create a basic singly linked list, add data and display the list's content. I tried writing a similar kinda program in C this time for Linux. There seems to be no compiler error or run-time error, but when I try to call the function void insert() , the program console tells me there is a segmentation error.
My code is included below :
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
}*nPtr;
nPtr head = NULL;
nPtr cur = NULL;
void insert(int Data);
void display();
int main(void)
{
int opr, data;
while (opr != 3)
{
printf("Choose operation on List. \n\n1. New Node. \n2. Display List.\n\n>>>");
scanf("%d", opr);
switch (opr)
{
case 1 :
printf("Enter data.\n");
scanf("%d", data);
insert(data);
break;
case 2 :
display();
break;
case 3 :
exit(0);
default :
printf("Invalid value.");
}
}
getchar();
}
void insert(int Data)
{
nPtr n = (nPtr) malloc(sizeof(nPtr));
if (n == NULL)
{
printf("Empty List.\n");
}
n->data = Data;
n->next = NULL;
if(head != NULL)
{
cur= head;
while (cur->next != NULL)
{
cur = cur->next;
}
cur->next = n;
}
else
{
head = n;
}
}
void display()
{
struct Node* n;
system("clear");
printf("List contains : \n\n");
while(n != NULL)
{
printf("\t->%d", n->data, "\n");
n = n->next;
}
}
When I run the code, there doesn't seem any problem or error at all. But when I call either of the 2 functions I created up there, there is an error which says "Segmentation fault". I'd assume something would be wrong with my malloc() function in void insert(), but I can't pin-point what's wrong in the void display() method.
The display() function never initializes n. The declaration should be:
nPtr n = head;

Having trouble with linked lists, program will not print the elements

I am supposed to do an assignment in C programming language. It includes linked lists and reading user input from the console.
The user inputs numbers into the console, for example ( 1 3 5 7 0 ), which are added, one by one, to the beginning of the linked list. 0 marks the end of the transition. This is what the linked list should look like after the first part: 7 5 3 1
I need to code two different functions that will delete different elements of the linked list.
First function deletes all elements from the list that have the value that you input, and second function deletes the element on the position that the user inputs, if it exists.
At the end, you should print the list.
I've written the the first function correctly, and I am sure about it, with the second function (the one that deletes elements on a certain position) I had some trouble. I made a simple function that counts how many nodes are there in total, so if someone puts a number larger than the amount of nodes, a message would pop up. I also used that function to make a for loop and used it as a limit when searching for the element on a certain position, if that makes any sense. The program also won't print anything, I have no idea why.
typedef struct Element Element;
struct Element
{
int number;
Element *next;
};
Element *addnewN(int number)
{
Element *newN = (Element*)malloc(sizeof(Element));
newN->number = number;
newN->next = NULL;
return newN;
}
Element *add_on_beginning(Element *head, Element *newN)
{
newN->next = head;
return head;
}
Element* delete_value(Element* head, int value)
{
Element *before = NULL;
Element *temp = head;
Element *newNhead = head;
while(temp != NULL)
{
if(temp->number == value)
{
if(before == NULL)
{
newNhead = temp->next;
free(temp);
temp = newNhead;
}
else
{
before->next = temp->next;
free(temp);
temp = before->next;
}
}
else
{
before = temp;
temp = temp->next;
}
}
return newNhead;
}
int counter(Element *head)
{
int count = 0;
Element *temp = head;
while(temp != NULL)
{
count++;
temp = temp->next;
}
return count;
}
Element* delete_on_position(Element* head, int position)
{
int limit = counter(head);
Element *temp = head;
Element *newNhead = head;
Element *before = NULL;
if(position > limit)
{
printf("Error.\n");
}
for(int i = 0; i < limit; i++)
{
if(position == 0)
{
newNhead = temp->next;
free(temp);
temp = newNhead;
}
else if(position == i)
{
before->next = temp->next;
free(temp);
temp = before->next;
}
else
{
before = temp;
temp = temp->next;
}
}
return head;
}
void printElement(Element *element)
{
printf("%d ", element->number);
}
void printList(Element *head)
{
Element *temp = head;
while(temp != NULL)
{
printElement(temp);
temp = temp->next;
}
}
void menu()
{
printf("\t MENU \n");
printf("1. Delete all elements from the list that have the value that
you input.\n");
printf("2. Delete the element on the position, if it exists.\n");
printf("3. Print the list. \n");
printf("4. Exit \n");
}
int main()
{
Element *head = NULL;
int i = 0;
int arr[1000];
char temp;
int x;
int y;
printf("Input the numbers you want: \n");
while(temp != '\n')
{
scanf("%d%c", &arr[i], &temp);
if(arr[i] == 0)
{
break;
}
head = add_on_beginning(head, addnewN(arr[i]));
i++;
}
menu();
while(1)
{
scanf("%d", &x);
switch(x)
{
case 1:
{
scanf("%d", &y);
head = delete_value(head, y);
break;
}
case 2:
{
scanf("%d", &y);
head = delete_on_position(head, y);
break;
}
case 3:
{
printList(head);
break;
}
case 4:
{
return 0;
}
}
}
return 0;
}
What you are supposed to get would be for example:
Input: 2 4 5 8 5 0 (in one line), and in one line each:
2
2
1
5
3
Output: 2 8
When debugged, the code does not show any errors.
add_on_beginning is not returning the correct value. It should return the node that was added, since it's the new head of the list. Nothing else will work correctly because of that, because head will always be NULL.
Element *add_on_beginning(Element *head, Element *newN)
{
newN->next = head;
return newN;
}

Correct way to delete a node in doubly circular linked list

The purpose of this code is to manage insertion and deletion and visualisation. I just want to know if I'm doing everything correctly, let me know if there are more possible ways to do this. This is my first attempt, i didn't follow any tutorial.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
int n;
struct Node *next;
struct Node *prev;
}TNode;
typedef TNode* Node;
void NewNode(Node *pp, int n)
{
Node temp, last;
temp = (Node)malloc(sizeof(struct Node));
temp->n = n;
temp->next = temp;
temp->prev = temp;
if(*pp != NULL)
{
last = (*pp)->prev;
temp->next = (*pp);
temp->prev = last;
last->next = (*pp)->prev = temp;
}
*pp = temp;
}
void ViewList(Node head)
{
if(head == NULL)
{
return;
}
Node node = head->prev;
do
{
printf("Curr: %d\n", node->n);
node = node->prev;
}while(node != head->prev);
}
void ReadData(Node * head, int * n)
{
printf("\nInsert a number:");
scanf("%d", n);
NewNode(head, *n);
}
Node SearchNode(Node head)
{
int d;
printf("\nElement to Delete:");
scanf("%d", &d);
while(head != NULL)
{
if(head->n == d)
{
return head;
}
head = head->next;
}
printf("\nNo Element [%d] Found", d);
return NULL;
}
void Delete(Node * head)
{
Node del = SearchNode(*head);
if(*head == NULL || del == NULL)
{
return;
}
if(*head == del && del->next == *head)
{
*head = NULL;
free(del);
return;
}
if(*head == del)
{
*head = del->next;
del->prev->next = *head;
(*head)->prev = del->prev;
free(del);
return;
}
if((*head)->prev == del)
{
(*head)->prev = del->prev;
del->prev->next = *head;
free(del);
return;
}
del->next->prev = del->prev;
del->prev->next = del->next;
free(del);
}
int Menu()
{
int c;
printf("\n*** M E N U ***\n"
"1 - New Node\n"
"2 - View List\n"
"3 - Delete\n"
"0 - Exit\n"
"\n>> ");
scanf(" %d", &c);
return c;
}
int main()
{
int c,n;
Node head = NULL;
do {
c = Menu();
switch (c)
{
case 1: ReadData(&head, &n); break;
case 2: ViewList(head); break;
case 3: Delete(&head); break;
default: c = 0;
}
} while (c != 0);
return 0;
}
How can i test if this is a real circular doubly linked list and not a simple doubly linked list?
Your program works fine, the only real bug I detected is in SearchNode: if the element is not present in the list, you enter an infinite loop. Your list is obviously a circular list and therefore you need to check if you have got back to the head in the function, which means that the element you're searching for is not in the list:
Corrected version:
Node SearchNode(Node head)
{
int d;
printf("\nElement to Delete:");
scanf("%d", &d);
Node start = head; // remember where we started
while (head != NULL)
{
if (head->n == d)
{
return head;
}
head = head->next;
if (head == start) // if we are back to where we started
break; // the element hasn't been found and we stop the loop
}
printf("\nNo Element [%d] Found", d);
return NULL;
}
There are also some design flaws, that don't prevent the program from working correctly:
One of them is this: The n variable is not used outside ReadData, so it's pointless to declare it in main and pass it's pointer to ReadData.
Corrected version:
void ReadData(Node * head)
{
int n; // declare n locally
printf("\nInsert a number:");
scanf("%d", &n);
NewNode(head, n);
}
Call it like this: ReadData(&head) and remove int n; from main.

linked list with function

I'm trying to create a program which creates and display linked list.
Now i'm having trouble with my create_list() function, it doesn't create any list.
What i'm doing wrong ?
Sorry for bad english :/
CODE :
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
int main(){
node *start;
start = NULL;
int a,n,on = 1;
while(on == 1){
printf(" \n choose: \n 1 --- create list \n 2 --- display list \n");
scanf("%d",&n);
switch(n){
case 1:
printf("-------------------------------------------- \n");
printf(" Enter the elements. The last element is 0 \n");
printf("-------------------------------------------- \n");
Create_list();
Display_list(start);
break;
case 2:
Display_list(start);
break;
}
}
system("pause");
return 0;
}
void Display_list(node *curr){
if(curr){
while (curr->next != NULL){
printf("%d \n",curr->data);
curr=curr->next;
}
} else {
printf(" \n The list is not created ! \n");
}
}
void Create_list(node *curr){
int i;
node *start = NULL;
if (start == NULL){
curr = (node *)malloc(sizeof(node));
start=curr;
while ( i != 0){
scanf("%d",&i);
if(i == 0){
curr->next=NULL;
curr=start;
} else {
curr->data=i;
curr->next=(node *)malloc(sizeof(node));
curr=curr->next;
}
}
} else {
printf(" \n list already exists ! \n");
}
}
The function Create_List(node *curr) needs some arguments. You are not passing any arguments from main(). Did your code compile?
The function Create_List(node *curr) needs some arguments. You are not passing any arguments from main(). Did your code compile?
What you should do is take a node in main which will store location of first node of the linked list.
void Insert(struct node **q, int num) //Num is the data to be added and **q is the pointer to the first node of the list.
{
struct node *temp, *r;
temp = *q;
if (*q == NULL) {
temp = ((struct node *)malloc(sizeof(struct node)));
temp->data = num;
temp->link = NULL;
*q = temp;
}
else {
while (temp->link != NULL)
temp = temp->link;
r = ((struct node *)malloc(sizeof(struct node)));
r->data = num;
r->link = NULL;
temp->link = r;
}
}
The start in Create_list is not related to the start in main. Since both are local to their respective functions, one can't even see the other. So setting start doesn't actually set start, if you will. :P
You'll need to either bring start outside of the functions and make it global, or pass &start (as a node**) from main into Create_list and modify *start to set the list head. (The latter is generally preferable, as globals are often trouble waiting to happen.)

Resources