L4 CS1201 LinkedList
L4 CS1201 LinkedList
– 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
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
a b c d
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
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.
A B C NUL
L
Composition of a Linked List
pHead pTail
payload
next
payload
payload next
next
Structure
A linked list uses linked allocation, and
therefore each node may appear anywhere in
memory
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
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.
head
A B C NULL
Types of Lists: Double Linked List
head tail
A B C
Defining a Node of a Double Linked List
• 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.
• 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
• 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:
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
ptr != null and thus we evaluate the loop and increment the pointer
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.
n1.next = &n2 ;
n2.next = &n3 ;
n3.next = NULL ; /* No more nodes follow */
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;
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;
if(newNode == NULL)
{
printf("Unable to allocate memory.");
break;
}
else
{
printf("Enter the data of node %d: ", i);
scanf("%d", &data);
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
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
• Ordering a list
• Reversing, sorting, etc.
Traversing a Linked List
Single Linked List: Traversing
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;
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 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.*/
if(newNode == NULL)
{
printf("Unable to allocate memory.");
}
else
{
newNode->data = data; //Links the data part
newNode->next = head; //Links the address
part
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;
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.*/
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;
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.
int main()
{
int n, data;
head = NULL;
last = 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;
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++;
oldNode = current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
delete oldNode;
current = head;
Insertion
head current
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
Step 2: Move the head to the second node of the linked list (head = head->next).
Single Linked List: Deletion at Front
if(head == NULL)
{
printf("List is already empty.");
}
else
{
toDelete = head;
head = head->next;
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 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;
if(toDelete == NULL)
break;
}
Deletion at any Position
if(toDelete != NULL)
{
if(toDelete == head)
head = head->next;
prevNode->next = toDelete->next;
toDelete->next = 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