














Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Community
Ask the community for help and clear up your study doubts
Discover the best universities in your country according to Docsity users
Free resources
Download our free guides on studying techniques, anxiety management strategies, and thesis advice from Docsity tutors
A comprehensive guide to linked lists in c programming, covering fundamental concepts, types of linked lists, and practical code examples for insertion, deletion, and sorting operations. It delves into the structure of singly and doubly linked lists, explaining their advantages and disadvantages. The document also includes a detailed explanation of algorithms for various linked list operations, making it a valuable resource for students and programmers learning about data structures.
Typology: Schemes and Mind Maps
1 / 22
This page cannot be seen from the preview
Don't miss anything!
A linked list is a collection of data elements called nodes in which the linear representation is given by links from one node to the next node. A linked list does not store its elements in consecutive memory locations and the user can add any number of elements to it. However, unlike an array, a linked list does not allow random access of data. Elements in a linked list can be accessed only in a sequential manner. But like an array, insertions and deletions can be done at any point in the list in a constant time.
A linked list, in simple terms, is a linear collection of data elements. These data elements are called nodes. Linked list is a data structure which in turn can be used to implement other data structures. Thus, it acts as a building block to implement data structures such as stacks, queues, and their variations. A linked list can be perceived as a train or a sequence of nodes in which each node contains one or more data fields and a pointer to the next node. In Fig. 6.1, we can see a linked list in which every node contains two parts, an integer and a pointer to the next node. The left part of the node which contains data may include a simple data type, an array, or a structure. The right part of the node contains a pointer to the next node (or address of the next node in sequence). The last node will have no next node connected to it, so it will store a special value called NULL. In Fig. 6.1, the NULL pointer is represented by X. While programming, we usually define NULL as – 1. Hence, a NULL pointer denotes the end of the list. Since in a linked list, every node contains a pointer to another node which is of the same type, it is also called a self-referential data type. Linked lists contain a pointer variable START that stores the address of the first node in the list. We can traverse the entire list using START which contains the address of the first node; the next part of the first node in turn stores the address of its succeeding node. Using this technique, the individual nodes of the list will form a chain of nodes. If START = NULL, then the linked list is empty and contains no nodes. In C, we can implement a linked list using the following code:
struct node { int data; struct node *next; }; TYPES OF LINKED LIST:
which the search is being made. If the search is successful, that is, VAL has been found, then the address of that node is stored in POS and the control jumps to the last statement of the algorithm. However, if the search is unsuccessful, POS is set to NULL which indicates that VAL is not present in the linked list. Consider above list search element 30 which give result position 3rd^ in list. If search element 60 which give result NULL. 3. Inserting a New Node in a Linked List: A new node is added into an already existing linked list. Three Types of insertion new node in linked list:
Algorithm: insertion_at_beginning Input: Data Output: -- The algorithm to insert a new node at the beginning of a linked list. In Step 1, we first check whether memory is available for the new node. If the free memory has exhausted, then an OVERFLOW message is printed. Otherwise, if a free memory cell is available, then we allocate space for the new node. Set its DATA part with the given VAL and the next part is initialized with the address of the first node of the list, which is stored in START. Now, since the new node is added as the first node of the list, it will now be known as the START node, that is, the START pointer variable will now hold the address of the NEW_NODE.
b. The new node is inserted at the end: Algorithm: insertion_at_end Input: Data Output: -- The algorithm to insert a new node at the end of a linked list. In Step 6, we take a pointer variable PTR and initialize it with START. That is, PTR now points to the first node of the linked list. In the while loop, we traverse through the linked list to reach the last node. Once we reach the last node, in Step 9, we change the NEXT pointer of the last node to store the address of the new node. c. The new node is insert a new node after a node: Algorithm: insertion_after_node Input: Data Output: --
Algorithm: deletion_end_node Input: -- Output: -- The algorithm to delete the last node from a linked list. In Step 2, we take a pointer variable PTR and initialize it with START. That is, PTR now points to the first node of the linked list. In the while loop, we take another pointer variable PREPTR such that it always points to one node before the PTR. Once we reach the last node and the second last node, we set the NEXT pointer of the second last node to NULL, so that it now becomes the (new) last node of the linked list. The memory of the previous last node is freed and returned back to the free pool. c. The node after a given node is deleted: Algorithm: deletion_given_node Input: Num (Data want to delete) Output: --
The algorithm to delete the node after a given node from a linked list. In Step 2, we take a pointer variable PTR and initialize it with START. That is, PTR now points to the first node of the linked list. In the while loop, we take another pointer variable PREPTR such that it always points to one node before the PTR. Once we reach the node containing VAL and the node succeeding it, we set the next pointer of the node containing VAL to the address contained in next field of the node succeeding it. The memory of the node succeeding the given node is freed and returned back to the free pool. Delete node with DATA(30) which present after DATA(20)
Write a program to create a linked list and perform insertions and deletions of all cases. Write functions to sort and finally delete the entire list at once. #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <malloc.h> struct node { int data; struct node *next; }; struct node *start = NULL; struct node *create_ll(struct node *); struct node *display(struct node *); struct node *insert_beg(struct node *); struct node *insert_end(struct node *); struct node *insert_before(struct node *);
{ ptr=start; while(ptr->next!=NULL) ptr=ptr->next; ptr->next = new_node; new_node->next=NULL; } printf(“\n Enter the data : “); scanf(“%d”, &num); } return start; } struct node *display(struct node *start) { struct node *ptr; ptr = start; while(ptr != NULL) { printf(“\t %d”, ptr - > data); ptr = ptr - > next; } return start; } struct node *insert_beg(struct node *start) { struct node *new_node; int num; printf(“\n Enter the data : “); scanf(“%d”, &num); new_node = (struct node *)malloc(sizeof(struct node)); new_node - > data = num; new_node - > next = start; start = new_node; return start; } struct node *insert_end(struct node *start) { struct node *ptr, *new_node; int num; printf(“\n Enter the data : “); scanf(“%d”, &num); new_node = (struct node *)malloc(sizeof(struct node)); new_node - > data = num; new_node - > next = NULL; ptr = start; while(ptr - > next != NULL) ptr = ptr - > next; ptr - > next = new_node; return start; } struct node *insert_before(struct node *start) { struct node *new_node, *ptr, *preptr; int num, val; printf(“\n Enter the data : “); scanf(“%d”, &num); printf(“\n Enter the value before which the data has to be inserted : “); scanf(“%d”, &val); new_node = (struct node *)malloc(sizeof(struct node)); new_node - > data = num; ptr = start; while(ptr - > data != val) { preptr = ptr; ptr = ptr - > next; } preptr - > next = new_node; new_node - > next = ptr; return start; } struct node *insert_after(struct node *start) {
struct node *new_node, *ptr, *preptr; int num, val; printf(“\n Enter the data : “); scanf(“%d”, &num); printf(“\n Enter the value after which the data has to be inserted : “); scanf(“%d”, &val); new_node = (struct node *)malloc(sizeof(struct node)); new_node - > data = num; ptr = start; preptr = ptr; while(preptr - > data != val) { preptr = ptr; ptr = ptr - > next; } preptr - > next=new_node; new_node - > next = ptr; return start; } struct node *delete_beg(struct node *start) { struct node *ptr; ptr = start; start = start - > next; free(ptr); return start; } struct node *delete_end(struct node *start) { struct node *ptr, *preptr; ptr = start; while(ptr - > next != NULL) { preptr = ptr; ptr = ptr - > next; } preptr - > next = NULL; free(ptr); return start; } struct node *delete_node(struct node *start) { struct node *ptr, *preptr; int val; printf(“\n Enter the value of the node which has to be deleted : “); scanf(“%d”, &val); ptr = start; if(ptr - > data == val) { start = delete_beg(start); return start; } else { while(ptr - > data != val) { preptr = ptr; ptr = ptr - > next; } preptr - > next = ptr - > next; free(ptr); return start; } } struct node *delete_after(struct node *start) { struct node *ptr, *preptr; int val; printf(“\n Enter the value after which the node has to deleted : “); scanf(“%d”, &val); ptr = start; preptr = ptr; while(preptr - > data != val) { preptr = ptr; ptr = ptr - > next;
prev will point to the node in the left side (or previous node) that is prev will hold the address of the previous node. next will point to the node in the right side (or next node) that is next will hold the address of the next node. DATA will store the information of the node. In C, the structure of a doubly linked list can be given as, struct node { struct node *prev; int data; struct node *next; }; The PREV field of the first node and the NEXT field of the last node will contain NULL. The PREV field is used to store the address of the preceding node, which enables us to traverse the list in the backward direction. **Doubly linked list Operation:
The algorithm to insert a new node at the beginning of a doubly linked list. In Step 1, we first check whether memory is available for the new node. If the free memory has exhausted, then an OVERFLOW message is printed. Otherwise, if free memory cell is available, then we allocate space for the new node. Set its DATA part with the given VAL and the NEXT part is initialized with the address of the first node of the list, which is stored in START. Now, since the new node is added as the first node of the list, it will now be known as the START node, that is, the START pointer variable will now hold the address of NEW_NODE. b. The new node is inserted at the end: Algorithm: doubly_insertion_end_node Input: VAL Output: --
2. Deleting a Node from a Linked List: a. The first node is deleted: Algorithm: doubly_deletion_first_node Input: -- Output: -- The algorithm to delete the first node of a doubly linked list. In Step 1 of the algorithm, we check if the linked list exists or not. If START = NULL, then it signifies that there are no nodes in the list and the control is transferred to the last statement of the algorithm. However, if there are nodes in the linked list, then we use a temporary pointer variable PTR that is set to point to the first node of the list. For this, we initialize PTR with START that stores the address of the first node of the list. In Step 3, START is made to point to the next node in sequence and finally the memory occupied by PTR (initially the first node of the list) is freed and returned to the free pool. b. The last node is deleted: Algorithm: doubly_deletion_last_node Input:-- Output:--
The algorithm to delete the last node of a doubly linked list. In Step 2, we take a pointer variable PTR and initialize it with START. That is, PTR now points to the first node of the linked list. The while loop traverses through the list to reach the last node. Once we reach the last node, we can also access the second last node by taking its address from the PREV field of the last node. To delete the last node, we simply have to set the next field of second last node to NULL, so that it now becomes the (new) last node of the linked list. The memory of the previous last node is freed and returned to the free pool.
Algorithm: doubly_deletion_after_node Input: NUM Output:-- The algorithm to delete a node after a given node of a doubly linked list. In Step 2, we take a pointer variable PTR and initialize it with START. That is, PTR now points to the first node of the doubly linked list. The while loop traverses through the linked list to reach the given node. Once we reach the node containing VAL, the node succeeding it can be easily
Implementation issues of the stack (Last In First Out - LIFO) using linked list.