05-DS-Linked List-2024
05-DS-Linked List-2024
head
10 20 20
Linked List
n Linked lists
n Abstract data type (ADT)
n Basic operations of linked lists
n Insert, find, delete, print, etc.
n Variations of linked lists
n Single linked lists
n Double linked lists
n Circular linked lists
Array versus Linked Lists
n Depending on the way in which the links are used to maintain adjacency,
several different types of linked lists are possible.
n Linear single-linked list (or simply linear list)
head
10 20 30
Single-linked lists vs. 1D-arrays
ID-array Single-linked list
Insertions and Deletions are inefficient: Insertions and Deletions are efficient: No
Elements are usually shifted shifting
head
10 20 30
Double Linked List
head tail
10 20 30
Why Linked List?
n Arrays can be used to store linear data of similar types, but arrays have
the following limitations.
n size of the arrays is fixed
n upper limit on the number of elements must know in advance.
n Allocated memory is for the total array irrespective of the usage.
n Creating a list
n Traversing the list
n Inserting an item in the list
n Deleting an item from the list
n Concatenating two lists into one
List is an Abstract Data Type
• What is an abstract data type?
– data type defined by the user
– Typically more complex than simple data types like int, float, etc.
• Why abstract?
– Because details of the implementation are hidden.
– When some operations on the list are performed, just the functions are called.
– Details of how the list is implemented or how the insert function is written is
no longer required.
Conceptual Idea
Insert
List
implementation
Delete
and the
related functions
Traverse
Structure of a Node
n Declare Node structure
n data: int-type data in this example
n next: a pointer to the next node in the list
struct Node {
int data; // data
struct Node* next; // pointer to next node
};
Create a List
void createList() {
int k, n;
struct Node *p, *head;
printf ("Number of nodes: ");
scanf ("%d", &n);
for (k=0; k<n; k++) {
if (k == 0) {
head = (struct Node *) malloc(sizeof(struct Node));
p = head;
}
else {
p->next = (struct Node *) malloc(sizeof(struct Node));
p = p->next;
}
scanf ("%d", &p->data);
}
p->next = NULL;
}
Traversing the List
n Once the linked list has been constructed and head points to the first node
of the list,
n Follow the pointers
n Display the contents of the nodes as they are traversed
n Stop when the next pointer points to NULL
Traversing the List
void display () {
int count = 1;
struct Node *p;
if(head == NULL) {
printf(“\nEmpty List...”);
return;
}
p = head;
while (p != NULL) {
printf ("\nNode: %d: %d", count, p->data);
count++;
p = p->next;
}
printf ("\n");
}
Inserting a Node in a List
Inserting a Node in a List
• Insert at beginning of the list:
– Only one next pointer needs to be modified.
• head is made to point to the new node.
• New node points to the previously first node.
Disadvantages:
1) Every node of DLL requires extra space for an previous pointer.
2) All operations require an extra pointer previous to be maintained.
§ For example, in insertion, need to modify previous pointers together with next
pointers.
Inserting at Beginning in a DLL
Inserting at Beginning in a DLL
void insertAtBegining() {
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
printf("\nEnter the new data: ");
scanf("%d", &newNode->data);
newNode->next = head;
new_node->prev = NULL;
if (head != NULL)
head->prev = newNode;
head = newNode;
}
Inserting at End in a DLL
Inserting at End in a DLL
void insertAtEnd() {
struct Node* last = head
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
printf("\nEnter the new data: ");
scanf("%d", &newNode->data);
newNode->next = NULL;
if (head == NULL) {
newNode->prev = NULL;
head = newNode;
return; }
while (last->next != NULL)
last = last->next;
last->next = newNode;
newNode->prev = last;
return; }
Inserting at Any Position in a DLL
Inserting at Any Position in a DLL
void insertAtAnyPosition() { if(curr->next == NULL) { insertAtEnd();
int i = 1, pos; return;}
struct Node* newNode, *curr; if(curr != NULL) {
curr = head; newNode = (struct Node*)
if(head == NULL) { malloc(sizeof(struct Node));
printf("\nEmpty list..."); printf("\nEnter the new data: ");
return; scanf("%d", &newNode->data);
} newNode->next = curr->next;
printf("\nEnter the position at which it will newNode->prev = curr;
be inserted: "); if(curr->next != NULL) curr->next->prev
scanf("%d", &pos); = newNode;
if(pos == 1) {insertAtBeginning(); return;} curr->next = newNode;
while(i< pos-1 && curr!=NULL) { }
curr = curr->next; else printf("Invalid position...\n"); }
i++; }
Delete node from the beginning of a
double linked list
Delete node from the beginning of a
double linked list
void deleteATBeginning() {
struct Node *temp;
if(head == NULL) {
printf("Empty List, Delete is not possible...\n");
return;
}
temp = head;
head = head->next;
if(head != NULL) head->prev = NULL;
free(temp);
}
Delete node from the end of a double
linked list
Delete node from the end of a double
linked list
void deleteAtEnd() {
struct Node *temp;
if(head == NULL) {
printf("Empty List, Delete is not possible...\n");
return;
}
temp = head;