21.INTRODUCTIONIn simplest terms, a list refers to a collection of data items of similar type arranged in sequence (that is, one after another). For example, list of students' names, list of addresses.. etc.One way to store such lists in memory is to use an array. However, arrays have certain problems associated with them. As array elements are stored in adjacent memory locations.a sufficient block of memory is allocated to array at compile-time. Once the memory is allocated to array, it cannot be expanded.That is why array is called a static data structure. If the number of elements to be stored in an array increases or decreases significantly at run-time, it may require more memory space or may result in wastage of memory, both of which are unacceptable.Another problem is that the insertion and deletion of an element into array are expensive operations, since they may require a number of elements to be shifted. Because of these problems, arrays are not generally used to implement linear lists instead another data structure known as linked list is used.A linked list is a linear collection of homogeneous elements called nodes. The successive nodes of a linked list need not occupy adjacent memory locations and the linear order between nodes is maintained by means of pointers.
3SINGLY LINKED LISTSa singly linked list (also called linear linked list), each node consists of two fields: inf o and next (see Figure 5.1). The info field contains the data and the next field contains the address of memory location where the next node is stored.The last node of the singly linked list contains NULL in its next field that indicates the end of list.A linked list contains a list pointer variable Start that stores the address of the firstNode of the list. In case, the Start contains NULL,the list is called an empty list or a null list.Figure 5.2 shows a singly linked list with four nodes.
4Memory Representation To maintain a linked list in memory, two parallel arrays of equal size are used.One array(say INFO) is used for the info field and another array (say, NEXT) for the next field of the nodes of the list.Figure 5.3 shows the memory representation of a linked list where each node contains an integer.In this figure, the pointer variable Start contains 25, that is, the address of first node of the list, which stores the value 37 in array INFO and its corresponding element in array NEXT stores 49, that is, the address of next node in the list and so on. Finally, the node at address 24 stores value 69 in array INFO and NULL in array NEXT, thus, it is the last node of the list.
5Memory AllocationAs memory is allocated dynamically to the linked list, a new node can be inserted anytime in the list.For this, the memory manager maintains a special linked list known as free storage list or memory bank or free pool that consists of unused memory cells.This list keeps track of the free space available in the memory and a pointer to this list is stored ina pointer variable Avail (see Figure 5.4). Note that the end of free-storage list is also denoted by storing NULL in the last available block of memory.In this figure, Avail contains 22, hence, INFO [ 2 2] is the starting point of the free storagelist. Since NEXT  contains 26, INFO  is the next free memory location.Similarly, other free spaces can be accessed and the NULL in NEXT  indicates the endof free-storage list.
6OperationsThese operations include traversing, searching, inserting and deleting nodes, reversing, sorting and merging linked lists.Creating a node means defining its structure, allocating memory to it and its initialization.As discussed earlier, the node of a linked list consists of data and a pointer to next node. To define a node containing an integer data and a pointer to next node in C language,we can use a self-referential structure whose definition is shown here.
8TraversingTraversing a list means accessing its elements one by one to process all or some of the elements.For example, if we need to display values of the nodes, count the number of nodes or search a particular item in the list, then traversing is required.We can traverse the list by using a temporary pointer variable (say, temp),which points to the node currently being processed.Initially, we make temp to point to the first node, process that element, then move temp to point to the next node using statement temp=temp- >next, process that element and moveso on as long as the last node is not reached, that is, until temp becomes NULL
9Insertion Insertion in Beginning: To insert a node in the beginning oflist, the next field of new node (pointed to by nptr) is made to point to the existing first node and the Start pointer is modified to point to the new node (see Figure 5.5).
10Insertion at EndTo insert a node at the end of a linked list, the list is traversed up to the last node and the next field of this node is modified to point to the new node.However, if the linked list is initially empty, then the new node becomes the first node and Start points to it.Figure 5.6(a) shows a linked list with a pointer variable temp pointing to its first node andFigure 5.6(b) shows temp pointing to the last node and the next field of last node pointing to the new node.
12Deletion Deletion from Beginning To delete a node from the beginning of a linked list, the address of the first node is stored in a temporary pointer variable temp and Start is modified to point to the second node in the linked list.After that the memory occupied by the node pointed to by temp is deallocated.Figure 5.8 shows the deletion of node from the beginning of a linked list.
13Deletion from EndTo delete a node from the end of a linked list, the list is traversed up to the last node.Two pointer variables save and temp are used to traverse the list, where save points to the node previously pointed by temp. At the end of traversing, temp points to the last node and save points to the second last node.Then the next field of the node pointed by save is made to point to NULL and the memory occupied by the node pointed to by temp is deallocated.Figure 5.9 shows the deletion of node from the end of a linked list.
23DOUBLY LINKED LISTSa singly linked list, each node contains a pointer to the next node and it has no information about its-previous node. Thus, we can traverse only in one direction, that is, from beginning to end.However, sometimes it is required to traverse in the backward direc that is, from end to beginning. This can be implemented by maintaining an additional pointer in each node of the list that points to the previous node. Such type of linked list is called doubly linked list.Each node ofa doubly linked list consists of three fields: prev, info and next (see 5.17). The info field contains the data, the prev field contains the address of the previous node and the next field contains the address of the next node.
24DOUBLY LINKED LISTSThe structure of a node of doubly linked list is shown here.