Você está na página 1de 9

Linked List

It is an arrangement where a set of nodes are connected to one another with the help of
pointers, forming a chain. A simple list looks like this.

Head Null value

Here, head pointer points to the first node of the list.

Node: An element containing a set of data values and a set of pointers pointing to other
similar elements. A very simple node may contain 1 data value and 1 pointer.

NULL: A pointer value which does not point to any location.

Linked list allocates space for each node separately. By using pointers to connect to all the
nodes together, the linked list forms a chain of nodes.
First node of the list is called the Head node and the address of this node is stored in
a special pointer variable, HEAD.
Last node of the list is called the Tail node. Pointer value of the tail node contains a
NULL, indicating the termination of the list at that point.
Unlike array, which uses contiguous memory to hold the values, linked list uses
dynamic allocation of non-contiguous memory to hold the node values.
Length of the list can grow without limits.
List can be traversed / navigated by following each pointer to the next node.
Nodes can be inserted or deleted from any location.
New nodes are inserted by breaking a connection, adding a new link, and restoring
the connection.
Nodes are deleted by breaking two connections, removing a link, and then
reconnecting the chain.
For insertions or deletions a maximum of 2 links are to be manipulated.
Linked list provides only sequential access to its elements, thus proves ineffective for
those applications where rapid searches are required.

Operations supported

Insert(): This operation inserts a node in the linked list. There exists many variations of
this operation. InsertFront (), InsertBack(), InsertData(), InsertAtPosition() are few of
them.
InsertFront () inserts a new head node.
InsertBack () inserts a new tail node.
InsertData () inserts a new node at an appropriate position in the already sorted list.
Here the position is decided by the data value present in the argument list. If a node
already exists in the list containing the same data value then, this scenario is
processed according to the need of the application at hand.
InsertAtPosition () inserts a new node at the desired position. It may be assumed
that the head node starts from position 1.
For all the insert operations, it is a must that we get hold of the address of the predecessor
node, i.e., address of that node which will become predecessor node to the new node after
the insertion is made.

Delete(): This operation deletes a node from the linked list. This operation also exists in
many variations. DeleteFront (), DeleteBack(), DeleteData(), DeleteAtPosition() are few of
them.
DeleteFront () deletes the head node, which results in the list having a new head
node (second node becomes the head node.). If the list has only one node then this
operation makes the list as empty.
DeleteBack () deletes the tail node. If the list has only one node then this operation
makes the list as empty.
DeleteData () deletes the node from an appropriate position in the already sorted list.
Here the position is decided by the data value present in the argument list. Repetitive
values are processed according to the need of the applications.
DeleteFromPosition () deletes the node from the desired position. It may be assumed
that the head node starts from position 1.

For all the delete operations, it is a must that we get hold of the address of the predecessor
node, to the node which is about to be deleted.

Length(): It returns the count of the number of present in the list.

Print(): It prints the node values on the screen.

Search(): It searches for the given argument data value in the list and returns are position
at which the node exists in the list. Unsuccessful search returns -1, an invalid position.
Repetitive values are processed according to the need of the applications.

Operations on linked lists

Inserting at the front
1. Allocate memory for the new node.
2. Initialize the node with the desired data value.
3. Have new node point to the old head node.
4. Update head node such that it points to the new node.



Inserting in the middle
1. Allocate memory for the new node.
2. Initialize the node with the desired data value.
3. Move the pointer to the previous node of the key node, i.e., the node before
which we want to insert.
4. Update the pointers such that the pointer value of the new node should point to
the next node in the list and the pointer value of the predecessor node should
point to the new node. Pointer assignments are shown below.


Inserting at the End
1. Allocate memory for the new node.
2. Initialize the node with the desired data value. Also initialize the address part of
the node with NULL.
3. Get the address to the last node.
4. Manipulate the pointer value of the last node such that, it points to the last node


DeleteNode

1. Get the address to the predecessor node of the node to be deleted.
2. Make a temporary pointer point to the node to be deleted.
3. Update the pointer value of the predecessor node such that, it points to the following
node of the node to be deleted.
4. Free the memory of the node to be deleted, with the help of the pointer used in
step 2.



Circular linked list

This data structure is a small variation over linked list. In the linked list, the address value
of the last node contains NULL. In circular list, the NULL value is substituted by the address
of the head node. This makes the first node adjacent to the last node, giving rise to an
impression as if the data structure is circular. Hence, the name, circular linked list.
Empty circular list contains one node
called the header node
contains irrelevant / unused data value
points to itself
header will point to the real first node in the list
last node will point to the header

Circular linked list with only one node may look as shown below.



One example of non empty circular list is as shown below.




Doubly linked list

The lists described above have a major drawback. They allow us to move only forward but
not backward. This problem is solved with the help of doubly linked list. Each node in this
list uses 2 pointers which help in moving forward and backward within the list. A simple
doubly linked list uses a node that contains two pointers and a data field, as shown below.


prev part contains the address of the predecessor node and next part contains the address
of the successor node.

A typical doubly linked list may look like as shown below.



Applications of Linked lists

Polynomial representation and manipulation.
A polynomial can be represented very easily using the linked list. Two polynomials
can also be manipulated using linked lists resulting in a new list.
Operating systems use linked lists to keep track of free memory blocks.
With few restrictions on the linked list data structure, stack and queue operations can
be implemented.
The logic of backward and forward buttons of Internet Explorer / Netscape
Navigator, the logic of undo and redo buttons of various text editors is
implemented based on the linked list.

Program

#include <stdio.h>
#include <malloc.h>

struct list
{
int data;
struct list *link;
};

typedef struct list node ;
node *head;

void create()
{
head = NULL;
}

int empty()
{
if (head == NULL)
return(1);
else
return(0);
}

int length()
{
node *temp = head;
int count = 0;
while(temp != NULL)
{
count++;
temp = temp->link;
}
return(count);
}

void insert(int pos)
{
node *temp, *prev;
int i;

if ((pos < 1) || (pos > length() + 1))
printf("Invalid position.\n");
else
{
temp = (node *) malloc(sizeof(node));
printf("Enter the data in the node : ");
scanf("%d",&temp->data);

if (pos == 1)
{
temp->link = head;
head = temp;
}
else
{
prev = head;
for(i = 0;i < pos - 2;i++)
prev = prev->link;
temp->link = prev->link;
prev->link = temp;
}
}
} /* end of insert() */

void del(int pos)
{
node *temp, *prev, *next;
int i;

if ((pos < 1) || (pos > length()))
printf("Invalid position.\n");
else
{
if (pos == 1)
{
temp = head;
head = head->link;
printf("Deleted node contains %d.\n",temp->data);
free(temp);
}
else
{
prev = head;
for(i = 0;i < pos - 2;i++)
prev = prev->link; /* Get the pointer to the previous node */
temp = prev->link; /* Get the pointer to the node to be deleted */
next = temp->link; /* Get the pointer to the next node */

prev->link = next; /* Connect the previous node to the next node */
printf("Deleted node contains %d.\n",temp->data);
free(temp);
}
}
}

void print()
{
node *temp = head;
if (temp == NULL)
printf("The list is empty.\n");
else
{
printf("Following is the list of elements : \n");
while(temp != NULL)
{
printf("%d\n",temp->data);
temp = temp->link;
}
}
}

void reverse()
{
node *p1, *p2, *p3;
if (head == NULL)
printf("List is already empty.\n");
else
{
p1 = head;
p2 = head->link;
while(p2 != NULL)
{
p3 = p2->link;
p2->link = p1;
p1 = p2;
p2 = p3;
}
head->link = NULL;
head = p1;
printf("List is now reversed.\n");
}
}

void menu()
{
printf("Following operations are allowed in the list : \n");
printf("1. Insert \n");
printf("2. Delete at the end\n");
printf("3. Reversal of the list\n");
printf("4. Length\n");
printf("5. Printing\n");
printf("6. Exit\n");
printf("Enter your choice : ");
}

void main()
{
int choice, pos, temp;

create();

do
{
menu();
scanf("%d",&choice);
switch(choice)
{
case 1 : printf("Enter the position: ");
scanf("%d",&pos);
insert(pos);
break;

case 2 : printf("Enter the position: ");
scanf("%d",&pos);
del(pos);
break;

case 3 : reverse();
break;

case 4 : temp = length();
printf("Length of the list = %d\n",temp);
break;

case 5 : print();
break;

case 6 : printf("Operations end, program terminates.\n");
break;

default : printf("Enter correct choice. Try again.\n");
} /* end of switch */
} while(choice != 6);
} /* end of main() */


Exercises

Implement the linked list program without using any of the global variables.
Write the recursive version of reverse().
Write the recursive version of length().
What additional improvements you may suggest in the above program?

Você também pode gostar