0% found this document useful (0 votes)
11 views110 pages

L4 CS1201 LinkedList

The document discusses Abstract Data Types (ADTs) and their implementations, focusing on data structures such as lists, stacks, and queues. It outlines the relationships between data, operations on data, and the differences between logical and physical forms of data. Additionally, it covers various types of linked lists, their structures, and advantages and disadvantages compared to arrays.

Uploaded by

rounak15jais24
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views110 pages

L4 CS1201 LinkedList

The document discusses Abstract Data Types (ADTs) and their implementations, focusing on data structures such as lists, stacks, and queues. It outlines the relationships between data, operations on data, and the differences between logical and physical forms of data. Additionally, it covers various types of linked lists, their structures, and advantages and disadvantages compared to arrays.

Uploaded by

rounak15jais24
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 110

Abstract Data Type (ADT)

Lists, Stack, Queue


Outline
Any form of information processing or communication
requires that data must be stored in and accessed from
either main or secondary memory

There are two questions we should ask:


– What do we want to do?
– How can we do it?

This topic will cover Abstract Data Types:


– Models of the storage and access of information
Relationships
Most interesting problems, however, have
questions associated with relationships:
– Which object has been stored the longest?
– Can I take CS1201 if I failed CS1101?
– Do both these pixels represent pavement on this
image?
– Can I get from here to Patna in under two
hours?
Relationships
six relationships:
– Linear orderings

– Hierarchical orderings

– Partial orderings

– Equivalence relations

– Weak orderings

– Adjacency relations
Operations
In any application, the actual required operations
may be only a subset of the possible operations
– In the design of any solution, it is important to consider
both current and future requirements
– Under certain conditions, by reducing specific
operations, the speed can be increased or the memory
decreased
Abstract Data Type
Abstract Data Type (ADT)
Specification for a group of values and
operations on those values
Data Structure
Implementation of an ADT within a
programming language
Bag
Collection
Object that groups other objects together
Provides various services to clients
add
remove
query
Abstract Data Type (ADT)
A collection of data and operations on that data
ADT operations can be used without knowing their implementations or
how data is stored
Data Structure
A construct that within a programming language to store a collection of data
An implementation of an ADT
Abstract Data Types
Any time you are intending to store objects, you
must ask:
– What are the relationships on the objects?
– What queries will be made about the objects in the
container?
– What operations will be performed on the objects in the
container?
– What operations may be performed on the container as
a whole?
– What queries will be made about the relationships
between the objects in the container?
– What operations may be made on the relationships
themselves between the objects in the container?
A Bag's Behaviors

Get the number of items currently in the bag


See whether the bag is empty √
Add a given object to the bag
Remove an occurrence of a particular object
from the bag, if possible
Remove all objects from the bag ??
(empty or clear the bag)
Count the number of times an object occurs in
the bag Bag
Test whether the bag contains a particular
object
Look at all objects in the bag
Abstract Data Type (ADT)
An ADT describes a set of objects sharing the same
properties and behaviors
– The properties of an ADT are its data
– The behaviors of an ADT are its operations or functions
– Classes

Thus, an ADT couples its data and operations


– OOP emphasizes data abstraction
Encapsulation: hide implementation details.
A data structure is the physical implementation of an ADT.
Logical vs. Physical Form
Data items have both a logical and a physical form.

Logical form:
definition of the data item within an ADT.

Physical form:
implementation of the data item within a data structure.
Logical vs. Physical Form-Example
Data items have both a logical and a physical form.

Logical/Conceptuak form:
definition of the data item within an ADT.

Physical form:
implementation of the data item within a data structure.
List ADT
ADT
Simple Stack ADT Example

int size()
Return the number of elements in the stack
bool isEmpty()
Indicate whether the stack is empty
void push( Object element )
Insert element at the top of the stack
Object top()
Return the top element on the stack without
removing it; an error occurs if the stack is
empty.
Object pop()
Remove and return the top element on the
stack; an error occurs if the stack is empty
Dictionary ADT Example
Operations in a Dictionary ADT:
int size()
bool isEmpty()
iter elements()
iter keys()
pos find( key )
iter findAll( key )
void insertItem( key, elem )
void removeElement( key )
void removeAllElements( key )
Linked List Basics
• Linked lists and arrays are similar since they both
store collections of data.
• The array's features all follow from its strategy of
allocating the memory for all its elements in one
block of memory.
• Linked lists use an entirely different strategy:
linked lists allocate memory for each element
separately and only when necessary.
Linked Data

?
4
7
25
12
34
75
?
3
1
6
8
Similarities and Differences Between
Arrays and Linked Lists

Similarities Differences
– Both store data in memory – Array is one block of contiguous memory
– Both store data in a sequence – List is a collection of scattered memory
cells

Array

Linked
List
Disadvantages of Arrays
1. The size of the array is fixed.
– In case of dynamically resizing the array from size S
to 2S, we need 3S units of available memory.
– Programmers allocate arrays which seem "large
enough” This strategy has two disadvantages: (a)
most of the time there are just 20% or 30% elements
in the array and 70% of the space in the array really is
wasted. (b) If the program ever needs to process more
than the declared size, the code breaks.
2. Inserting (and deleting) elements into the
middle of the array is potentially expensive
because existing elements need to be shifted over
to make room
Linked lists
• Linked lists are appropriate when the number of
data elements to be represented in the data
structure at once is unpredictable.
• Linked lists are dynamic, so the length of a list can
increase or decrease as necessary.
• Each node does not necessarily follow the
previous one physically in the memory.
• Linked lists can be maintained in sorted order by
inserting or deleting an element at the proper point
in the list.
Definitions
• Linked List
• A data structure in which each element is dynamically
allocated and in which elements point to each other to define a
linear relationship
• Singly- or doubly-linked
• Stack, queue, circular list
Singly Linked Lists
head

next next next next

a b c d

First node Last node


Empty List
• Empty Linked list is a single pointer having the
value of NULL.

head = NULL;

head
Defining a Node of a Linked List
Each structure of the list is called a node, and consists of two fields:
• Item (or) data
• Address of the next item in the list (or) pointer to the next node in the
list

How to define a node of a linked list?

struct node node


{
int data; /* Data */ Data
next
struct node *next; /* pointer*/
};

Note:
Such structures which contain a member field pointing to the same
structure type are called self-referential structures.
Types of Lists: Single Linked List
Depending on the way in which the links are used to maintain
adjacency, several different types of linked lists are possible.

Single linked list (or simply linked list)


• A head pointer addresses the first element of the list.
• Each element points at a successor element.
• The last element has a link value NULL.
head

A B C NUL
L
Composition of a Linked List

A linked list is called “linked” because each node in the series


(i.e. the chain) has a pointer to the next node in the list, e.g.

a) The list head is a pointer to the first node in the list.


b) Each node in the list points to the next node in the list.
c) The last node points to NULL (the usual way to signify the end).

pHead pTail

struct Node { struct Node { struct Node {


char element; char element; char element;
Node *next;
*next; Node *next;
*next; Node *next;
*next;
NULL
}; }; };
Linked List
struct listItem {
type payload;
struct listItem *next;
}; payload
next

payload
next
payload
payload next
next
Structure
A linked list uses linked allocation, and
therefore each node may appear anywhere in
memory

Also the memory required for each node


equals the memory required by the member
variables
– 4 bytes for the linked list (a pointer)
– 8 bytes for each node (an int and a pointer)
• We are assuming a 32-bit machine
Structure
Such a list could occupy memory as follows:

Linked List Objec


Structure
The next_node pointers store the addresses
of the next node in the list
Structure
Because the addresses are arbitrary, we can
remove that information:
Linked List (continued)
• Items of list are usually same type
• Generally obtained from malloc()
• Each item points to next item
• Last item points to null
• Need “head” to point to first item!

• “Payload” of item may be almost anything


• A single member or multiple members
• Any type of object whose size is known at compile time
• Including struct, union, char * or other pointers
• Also arrays of fixed size at compile time
Usage of Linked Lists

• Not massive amounts of data


• Linear search is okay
• Sorting not necessary
• or sometimes not possible
• Need to add and delete data “on the fly”
• Even from middle of list
• Items often need to be added to or deleted
from the “ends”
Linked List (continued)
struct listItem {
type payload;
struct listItem *next;
};
struct listItem *head;
payload
payload next
next
payload
payload
next
next
Linked Lists in C
Defining a Node of a Linked List

Each structure of the list is called a node, and consists of two fields:
• Item (or) data
• Address of the next item in the list (or) pointer to the next node in the list

How to define a node of a linked list?

struct node
node
{
int data; /* Data */ Data
struct node *next; /* next
pointer*/
} ;

Note:
Such structures which contain a member field pointing to the same
structure type are called self-referential structures.
Types of Lists: Single Linked List
Depending on the way in which the links are used to
maintain adjacency, several different types of linked
lists are possible.

Single linked list (or simply linked list)


• A head pointer addresses the first element of the list.
• Each element points at a successor element.
• The last element has a link value NULL.

head

A B C NULL
Types of Lists: Double Linked List

Double linked list


• Pointers exist between adjacent nodes in both directions.
• The list can be traversed either forward or backward.
• Usually two pointers are maintained to keep track of the list, head
and tail.

head tail

A B C
Defining a Node of a Double Linked List

Each node of doubly linked list (DLL) consists of three


fields:
• Item (or) Data
• Pointer of the next node in DLL node
• Pointer of the previous node in DLL
Data
prev next
How to define a node of a doubly
linked list (DLL)?
struct node
{
int data;
struct node *next; // Pointer to next node in DLL
struct node *prev; // Pointer to previous node in DLL
};
Double Linked List
• Doubly linked list is a collection of nodes linked together in a sequential
way.

• Doubly linked list is almost similar to singly linked list except it contains
two address or reference fields, where one of the address field contains
reference of the next node and other contains reference of the previous
node.

• First and last node of a linked list contains a terminator generally a NULL
value, that determines the start and end of the list.

• Doubly linked list is sometimes also referred as bi-directional linked list


since it allows traversal of nodes in both direction.

• Since doubly linked list allows the traversal of nodes in both direction, we
can keep track of both first and last nodes.
Doubly-Linked List
struct listItem {
type payload;
listItem *prev;
listItem *next;
};
struct listItem *head, *tail;

payload payload
prev next prev next payload
payload prev next
prev next
Double versus Single Linked List
Advantages over singly linked list

1)A DLL can be traversed in both forward


and backward direction.
2)The delete operation in DLL is more
efficient if pointer to the node to be
deleted is given.

Disadvantages over singly linked list


1)Every node of DLL Require extra space
for an previous pointer.
2)All operations require an extra pointer
previous to be maintained.
Types of Lists: Circular Linked List

Circular linked list


• The pointer from the last element in
the list points back to the first
element.
hea
d
A B C
Circular Linked List
• A circular linked list is basically a linear linked list that may be single- or
double-linked.

• The only difference is that there is no any NULL value terminating the
list.

• In fact in the list every node points to the next node and last node points
to the first node, thus forming a circle. Since it forms a circle with no end
to stop it is called as circular linked list.

• In circular linked list there can be no starting or ending node, whole node
can be traversed from any node.

• In order to traverse the circular linked list, only once we need to traverse
entire list until the starting node is not traversed again.

• A circular linked list can be implemented using both singly linked list
Stepping through a Linked List
The process of stepping through a linked list can be thought of as
being analogous to a for-loop:
•We initialize a temporary pointer with the list
head
•We continue iterating until the pointer equals
NULL
•With each step, we set the pointer to point to the
next object
Stepping through a Linked List
we have:
for ( Node *ptr = begin(head); ptr != end(); ptr = ptr->next() ) {
// do something
// use ptr->next
// use ptr->var to assign/access variables
}
Stepping through a Linked List

Analogously:

for ( Node *ptr = begin(); ptr != end(); ptr = ptr->next() )


for ( int i = 0; i != N; ++i )
Stepping through a Linked List
With the initialization and first iteration of the loop, we have:

ptr != NULL and thus we evaluate the body of the loop and then
set ptr to the next pointer of the node it is pointing to
Stepping through a Linked List

With the initialization and first iteration of the loop, we have

ptr != nullptr and thus we evaluate the body of the loop


and then set ptr to the next pointer of the node it is pointing to
Stepping through a Linked List
ptr != nullptr and thus we evaluate the loop and increment the
pointer

In the loop, we can access the value being pointed to by using


ptr->value()
Stepping through a Linked List

ptr != NULL and thus we evaluate the loop and


increment the
pointer

Also, in the loop, we can access the next node in


the list by using ptr->next()
Stepping through a Linked List

ptr != null and thus we evaluate the loop and increment the pointer

This last increment causes ptr == nullptr


Stepping through a Linked List

Here, we check and find ptr != null is false, and thus we exit
the loop
Example 1: Creating a Single Linked List
Linked list to store and print roll number, name and age of 3
students.
#include <stdio.h>
struct stud
{
int roll;
char name[30];
int age;
struct stud *next;
};
main()
{
struct stud n1, n2, n3;
struct stud *p;
scanf (“%d %s %d”, &n1.roll, n1.name, &n1.age);
scanf (“%d %s %d”, &n2.roll,n2.name, &n2.age);
scanf (“%d %s %d”, &n3.roll,n3.name, &n3.age);
Example 1: Creating a Single Linked List

n1.next = &n2 ;
n2.next = &n3 ;
n3.next = NULL ;
/* Now traverse the list and print the elements
*/
p = &n1 ; /* point to 1st element */
while (p != NULL)
{
printf (“\n %d %s %d”, p->roll, p->name,
p->age);
p = p->next;
}
}
Example 1: Illustration

The structure:

struct stud
{
int roll;
char name[30];
int age;
struct stud *next;
};
Also assume the list with three nodes n1, n2 and n3 for 3
students.

struct stud n1, n2, n3;


Example 1: Illustration
To create the links between nodes, it is written as:

n1.next = &n2 ;
n2.next = &n3 ;
n3.next = NULL ; /* No more nodes follow */

• Now the list looks like:

roll
name
ag
e
next NULL
n1 n2 n3
Example 2: Creating a Single Linked
List
C-program to store 10 values on a linked list reading the data from keyboard
#include <stdio.h>
#include <stdlib.h>

struct node {
int data; //Data part
struct node *next; //Address part
}*header;

void createList(int n); /* Functions to create a list*/

int main()
{
int n;
printf("Enter the total number of nodes: ");
scanf("%d", &n);
createList(n);
return 0;
Example 2: Creating a Single Linked List
void createList(int n)
{
struct node *newNode, *temp;
int data, i;

/* A node is created by allocating memory to a structure */


newNode = (struct node *)malloc(sizeof(struct node));

/* If unable to allocate memory for head node */


if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
printf("Enter the data of node 1: ");
scanf("%d", &data);

newNode->data = data; //Links the data field with data


newNode->next = NULL; //Links the address field to NULL
header = newNode; //Header points to the first node
temp = newNode; //First node is the current node
Example 2: Creating a Single Linked
List
for(i=2; i<= n; i++)
{
/* A newNode is created by allocating memory */
newNode = (struct node *)malloc(sizeof(struct node));

if(newNode == NULL)
{
printf("Unable to allocate memory.");
break;
}
else
{
printf("Enter the data of node %d: ", i);
scanf("%d", &data);

newNode->data = data; //Links the data field of newNode with data


newNode->next = NULL; //Links the address field of newNode with NULL

temp->next = newNode; //Links previous node i.e. temp to the newNode


temp = temp->next;
}
}
}
}
Example 2: Illustration
• To start with, we have to create a node (the first node), and
make header point to it.
newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = data; //Links the data field with data
newNode->next = NULL; //Links the address field to NULL
header = newNode;
temp = newNode;
It creates a single node. For example, if the data entered is 100 then the list
look like

header
100 NUL
L
Creating a Single Linked List
If we need n number of nodes in the linked list:
• Allocate n newNodes, one by one.
• Read in the data for the newNodes.
• Modify the links of the newNodes so that the chain is formed.
newNode = (struct node *)malloc(sizeof(struct node));
newNode->data = data; //Links the data field of newNode
with data
newNode->next = NULL; //Links the address field of newNode
with NULL
temp->next = newNode; //Links previous node i.e. temp to
the newNode
temp = temp->next;

It creates n number of nodes . For e.g. if the data entered is 200, 50, 30 then
the list look like
head
10 20 50 30 NUL
0 0 L
Example 3: Creating a Single Linked List
C-program to copy an array to a single linked list.
#include <stdio.h>
#include <stdlib.h>

struct node {
int data; //Data part
struct node *next; //Address part
};

int main()
{
struct node *header, *newNode, *temp;
int data, i, n, a[100];
printf("Enter the total number of data: ");
scanf("%d", &n);
// Write code here to initialize the array a with n
elements //

...
Example 2: Creating a Single Linked List

/* A node is created by allocating memory to a structure */


newNode = (struct node *)malloc(sizeof(struct node));

/* If unable to allocate memory for head node */


if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = a[0]; //Links the data field with data
newNode->next = NULL; //Links the address field to NULL
header = newNode; //Header points to the first node
temp = header;
Example 2: Creating a Single Linked List
for(i = 1; i <= n; i++)
{
/* A newNode is created by allocating memory */
newNode = (struct node *)malloc(sizeof(struct node));

if(newNode == NULL)
{
printf("Unable to allocate memory.");
break;
}
else
{
newNode->data = a[i]; //Links the data field of newNode with a[i]
newNode->next = NULL; //Links the address field of newNode with NULL

temp->next = newNode; //Links previous node i.e. temp to the newNode


temp = temp->next;
}
}
}
}
Operations on Linked Lists
Operations on single linked list
• Traversing a list
• Printing, finding minimum, etc.

• Insertion of a node into a list


• At front, end and anywhere, etc.

• Deletion of a node from a list


• At front, end and anywhere, etc.

• Comparing two linked lists


• Similarity, intersection, etc.

• Merging two linked lists into a larger list


• Union, concatenation, etc.

• Ordering a list
• Reversing, sorting, etc.
Traversing a Linked List
Single Linked List: Traversing

Once the linked list has been constructed and header


points to the first node of the list,
• Follow the pointers.
• Display the contents of the nodes as they are traversed.
• Stop when the next pointer points to NULL.

The function traverseList(struct Node *) is given in the next


slide. This function to be called from main() function as:

int main()
{
// Assume header, the pointer to the linked list is given as an
input
printf("\n Data in the list \n");
traverseList(header);
return 0;
}
Single linked list: Traversing
void traverseList(struct Node *header)
{
struct node *temp;

/* If the list is empty i.e. head = NULL */


if(header == NULL)
{
printf("List is empty.");
}
else
{
temp = header;
while(temp != NULL)
{
printf("Data = %d\n", temp->data); //Prints the data
of current node
temp = temp->next; //Advances the position of
current node
}
}
Insertion in a Linked List
Single Linked List: Insertion

Insertion steps:
• Create a new node
• Start from the header node
• Manage links to
• Insert at front
• Insert at end
• Insert at any position
Insertion at Front
Steps to insert node at the beginning of singly linked list

Step 1: Create a new node.


Insertion at Front
Step 2: Link the newly created node with the head node, i.e. the newNode will now
point to head node.

Step 3: Make the new node as the head node, i.e. now head node will point to newNode.
Insertion at front
/*Create a new node and insert at the beginning of the
linked list.*/

void insertNodeAtBeginning(int data)


{
struct node *newNode;
newNode = (struct node*)malloc(sizeof(struct node));

if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = head; //Links the address
part

head = newNode; //Makes newNode as first


node

printf("DATA INSERTED SUCCESSFULLY\n");


}
Single Linked List: Insertion at End
Steps to insert node at the end of Singly linked list
Step 1: Create a new node and make sure that the address part of the new node points to
NULL. i.e. newNode->next=NULL

Step 2: Traverse to the last node of the linked list and connect the last node of the list with the new
node, i.e. last node will now point to new node. (lastNode->next = newNode).
Insertion at End
/* Create a new node and insert at the end of the linked
list. */
void insertNodeAtEnd(int data)
{
struct node *newNode, *temp;
newNode = (struct node*)malloc(sizeof(struct node));
if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = NULL;
temp = head;

while(temp->next != NULL) //Traverse to the last node


temp = temp->next;

temp->next = newNode; //Links the address part


printf("DATA INSERTED SUCCESSFULLY\n");
}
Single Linked List Insertion at Any Position

Steps to insert node at any position of Singly Linked List


Step 1: Create a new node.

Step 2: Traverse to the n-1th position of the linked list and connect the new node with the
n+1th node. (newNode->next = temp->next) where temp is the n-1th node.
Single Linked List: Insertion at any position

Step 3: Now at last connect the n-1th node with the new node i.e. the n-1th node
will now point to new node. (temp->next = newNode) where temp is the n-1th
node.
Insertion at any Position
/* Create a new node and insert at middle of the linked
list.*/

void insertNodeAtMiddle(int data, int position)


{
int i;
struct node *newNode, *temp;

newNode = (struct node*)malloc(sizeof(struct node));

if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = NULL;

temp = head;
Insertion at any Position
for(i=2; i<=position-1; i++) /* Traverse to the n-1 position */
{
temp = temp->next;

if(temp == NULL)
break;
}
if(temp != NULL)
{
/* Links the address part of new node */
newNode->next = temp->next;

/* Links the address part of n-1 node */


temp->next = newNode;

printf("DATA INSERTED SUCCESSFULLY\n");


}
else
{
printf("UNABLE TO INSERT DATA AT THE GIVEN POSITION\n");
}
}
}
Double Linked List: Insertion at any Position

Steps to insert a new node at nth position in a


Doubly linked list.

Step 1: Traverse to N-1 node in the list, where N is


the position to insert. Say temp now points to N-
1th node.

Step 2: Create a newNode that is to be inserted


and assign some data to its data field.
Doubly Linked List: Insertion at any Position
Step 3: Connect the next address field of newNode with the node pointed by next
address field of temp node.

Step 4: Connect the previous address field of newNode with the temp node.
Doubly Linked List: Insertion at any Position

Step 5: Check if temp.next is not NULL then, connect the previous address field of
node pointed by temp.next to newNode.

Step 6: Connect the next address field of temp node to newNode.


Doubly Linked List: Insertion at any Position

Step 7: Final doubly linked list looks like


Doubly Linked List: Insertion at any Position
#include <stdio.h>
#include <stdlib.h>

struct node { /* Basic structure of Node */


int data;
struct node * prev;
struct node * next;
}*head, *last;

int main()
{
int n, data;
head = NULL;
last = NULL;

printf("Enter the total number of nodes in list: ");


scanf("%d", &n);
createList(n); // function to create double linked list
displayList(); // function to display the list

printf("Enter the position and data to insert new node: ");


scanf("%d %d", &n, &data);
insert_position(data, n); // function to insert node at any position
displayList();
return 0;
}
Doubly Linked List: Insertion at any Position
void createList(int n)
{
int i, data;
struct node *newNode;
if(n >= 1){ /* Creates and links the head node */
head = (struct node *)malloc(sizeof(struct node));
printf("Enter data of 1 node: ");
scanf("%d", &data);
head->data = data;
head->prev = NULL;
head->next = NULL;

last = head;

for(i=2; i<=n; i++){ /* Creates and links rest of the n-1 nodes */
newNode = (struct node *)malloc(sizeof(struct node));
printf("Enter data of %d node: ", i);
scanf("%d", &data);

newNode->data = data;
newNode->prev = last; //Links new node with the previous node
newNode->next = NULL;

last->next = newNode; //Links previous node with the new node


last = newNode; //Makes new node as last/previous node
}
printf("\nDOUBLY LINKED LIST CREATED SUCCESSFULLY\n");
}
}
Doubly Linked List: Insertion at any Position
void insert_position(int data, int position)
{
struct node * newNode, *temp;
if(head == NULL){
printf("Error, List is empty!\n");
}
else{
temp = head;
if(temp!=NULL){
newNode = (struct node *)malloc(sizeof(struct node));

newNode->data = data;
newNode->next = temp->next; //Connects new node with n+1th node
newNode->prev = temp; //Connects new node with n-1th node

if(temp->next != NULL)
{
temp->next->prev = newNode; /* Connects n+1th node with new node */
}
temp->next = newNode; /* Connects n-1th node with new node */
printf("NODE INSERTED SUCCESSFULLY AT %d POSITION\n", position);
}
else{
printf("Error, Invalid position\n");
}
}
}
Doubly Linked List: Insertion at any Position
void displayList()
{
struct node * temp;
int n = 1;

if(head == NULL)
{
printf("List is empty.\n");
}
else
{
temp = head;
printf("DATA IN THE LIST:\n");

while(temp != NULL)
{
printf("DATA of %d node = %d\n", n, temp->data);
n++;

/* Moves the current pointer to next node */


temp = temp->next;
}
}
}
Deletion
head current

oldNode = current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
delete oldNode;
current = head;
Insertion
head current

newNode = new Node(x);


newNode->prev = current; newNode
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Deletion from a Linked List
Single Linked List: Deletion

Deletion steps
• Start from the header node
• Manage links to
• Delete at front
• Delete at end
• Delete at any position
• freeingup the node as free space.
Free Memory after Deletion

• Do not forget to free() memory location dynamically allocated


for a node after deletion of that node.

• It is the programmer’s responsibility to free that memory


block.

• Failure to do so may create a dangling pointer – a memory,


that is not used either by the programmer or by the system.

• The content of a free memory is not erased until it is


overwritten.
Single Linked List: Deletion at Front

Steps to delete first node of Singly Linked List


Step 1: Copy the address of first node i.e. head node to some temp variable say toDelete.

Step 2: Move the head to the second node of the linked list (head = head->next).
Single Linked List: Deletion at Front

Step 3: Disconnect the connection of first node to second node.

Step 4: Free the memory occupied by the first node.


Deletion at Front
/* Delete the first node of the linked list */
void deleteFirstNode()
{
struct node *toDelete;

if(head == NULL)
{
printf("List is already empty.");
}
else
{
toDelete = head;
head = head->next;

printf("\nData deleted = %d\n", toDelete->data);

/* Clears the memory occupied by first node*/


free(toDelete);

printf("SUCCESSFULLY DELETED FIRST NODE FROM LIST\n");


}
}
Single Linked List: Deletion at End

Steps to delete last node of a Singly Linked List


Step 1: Traverse to the last node of the linked list keeping track of the second last node in
some temp variable say secondLastNode.

Step 2: If the last node is the head node then make the head node as NULL else
disconnect the second last node with the last node i.e. secondLastNode->next =
NULL
Single Linked List: Deletion at End

Step 3: Free the memory occupied by the last node.


Deletion at End
/* Delete the last node of the linked list */
void deleteLastNode()
{
struct node *toDelete, *secondLastNode;
toDelete = head;
secondLastNode = head;

while(toDelete->next != NULL) /* Traverse to the last node of


the list*/
{
secondLastNode = toDelete;
toDelete = toDelete->next;
}
if(toDelete == head)
{
head = NULL;
}
else
{
/* Disconnects the link of second last node with last node */
secondLastNode->next = NULL;
}
/* Delete the last node */
free(toDelete);
}
Single Linked List: Deletion at any Position

Steps to delete a node at any position of Singly Linked List


Step 1: Traverse to the nth node of the singly linked list and also keep reference of n-1th
node in some temp variable say prevNode.

Step 2: Reconnect n-1th node with the n+1th node i.e. prevNode->next = toDelete->next
(Where prevNode is n-1th node and toDelete node is the nth node and toDelete->next is the n+1th
node).
Single Linked List: Deletion at any Position

Step 3: Free the memory occupied by the nth node i.e. toDelete node.
Deletion at any Position
/* Delete the node at any given position of the linked
list */
void deleteMiddleNode(int position)
{
int i;
struct node *toDelete, *prevNode;
if(head == NULL)
{
printf("List is already empty.");
}
else
{
toDelete = head;
prevNode = head;

for(i=2; i<=position; i++)


{
prevNode = toDelete;
toDelete = toDelete->next;

if(toDelete == NULL)
break;
}
Deletion at any Position

if(toDelete != NULL)
{
if(toDelete == head)
head = head->next;

prevNode->next = toDelete->next;
toDelete->next = NULL;

/* Deletes the n node */


free(toDelete);

printf("SUCCESSFULLY DELETED NODE FROM MIDDLE OF LIST\n");


}
else
{
printf("Invalid position unable to delete.");
}
}
}
Comparing Two Linked Lists
Single Linked List: Comparing two Lists

Comparing two linked list includes


• Identifying whether the given two linked list are identical.
• Two Linked Lists are identical when they have same data and
arrangement of data is also same.

• Checking whether the lists have same values when the


arrangement is not same.
Comparing two Linked Lists
/* Return true if linked lists a and b are identical,
otherwise false */
bool areIdentical(struct node *a, struct node *b)
{
while (a != NULL && b != NULL)
{
if (a->data != b->data)
return false;
/* If we reach here, then a and b are not NULL and
their data is same, so move to next nodes in both lists */
a = a->next;
b = b->next;
}
//If linked lists are identical, then 'a' and 'b' must
be NULL at this point.
return (a == NULL && b == NULL);
}

int main()
{
struct node *a, *b;
a = createList(5); // e.g: a: 5->4->3->2->1
b = createList(5); // e.g: b: 5->4->3->2->1
areIdentical(a, b)? printf("Identical"): printf("Not
identical");
return 0;
}
Next-Other Kinds of List Structures

• Queue — FIFO (First In, First Out)


• Items added at end
• Items removed from beginning
• Stack — LIFO (Last In, First Out)
• Items added at beginning, removed from beginning

You might also like