Linked Lists1
Linked Lists1
1
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Abstract Data Types
2
Definition
An abstract data type (ADT) is a specification of a set of data and the set of
operations that can be performed on the set of data.
Such a data type is abstract in the sense that it is independent of various concrete
implementations.
• To perform some operation on the ADT, we just call a function.
• Details of how the ADT is implemented or how the functions are written is not
required to be known.
• Even if the underlying implementations of the functions are changed, as long
as the function interfaces remain the same, we can continue using the ADT in
the same way
3
Example 1: List (a sequence of data items of the same type)
Create
Insert List
implementation
Delete and the
related functions
We shall later look into a concrete
Traverse
way of implementing a list
4
Example 2 :: Set
union
intersect
minus
Set
insert
delete
size
5
Example 2 :: Set
6
Example 3 :: Last-In-First-Out STACK
push
pop
create
STACK
isempty
isfull
7
Visualization of a Stack
In Out
C B A B C
8
Example 3 :: Last-In-First-Out STACK
Assume:: stack contains integer elements
void push (stack s, int element);
/* Insert an element in the stack */
int pop (stack s);
/* Remove and return the top element */
void create (stack s);
/* Create a new stack */
int isempty (stack s);
/* Check if stack is empty */ We shall later look into a concrete
way of implementing a stack
int isfull (stack s);
/* Check if stack is full */
9
Example 4 :: First-In-First-Out QUEUE
enqueue
dequeue
create
QUEUE
isempty
size
10
Visualization of a Queue
Out
In
B A
C B A
11
Example 4 :: First-In-First-Out QUEUE
Assume:: queue contains integer elements
void enqueue (queue q, int element);
/* Insert an element in the queue */
int dequeue (queue q);
/* Remove an element from the queue */
queue *createq();
/* Create a new queue */
int isempty (queue q);
/* Check if queue is empty */ We shall later look into a concrete
way of implementing a queue
int size (queue q);
/* Return the no. of elements in queue */
12
Lists
13
List (a sequence of data items of the same type)
Create
Insert List
implementation
Delete and the
related functions
Traverse
14
Lists
• List is a sequence of data items of same type.
• Array – one way to represent a list.
• Advantages of arrays:
• Compact; no wastage of space
• Easy and constant time access given index of an element
15
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Self-Referential Structures
A structure referencing itself – how?
So, we need a pointer inside a structure that points to a structure of the same type.
struct list {
int data;
struct list *next;
};
Self-Referential Structures
struct list {
int data ;
struct list * next ;
};
NULL
struct list a, b, c;
a b c
1 NULL 2 NULL 3 NULL
data next data next data next
Chaining these together
[Link] = &b;
[Link] = &c;
a b c
1 2 3 NULL
data next data next data next
A B C D NULL
Header file : list.h Our own header file !!
head n NULL
Storage allocation
head->next = (LINK) malloc (sizeof(ELEMENT));
Remember:
head->next->d = ‘e’;
typedef struct list ELEMENT;
head->next->next = NULL; typedef ELEMENT* LINK;
head n e NULL
Storage allocation
head->next->next = (LINK) malloc (sizeof(ELEMENT));
Remember:
head->next->next->d = ‘w’;
head->next->next->next = NULL; typedef struct list ELEMENT;
typedef ELEMENT* LINK;
head n e w NULL
Operations on Lists
28
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Produce a list from a string (each character in a node)
LINK StrToList (char s[ ]) {
LINK head = NULL, tail; s H E L L O \0
int i;
30
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Inserting at the Head 1. Allocate a new node
2. Insert new element
3. Make new node point to old head
head X Y
4. Update head to point to new node
head X Y
head X Y
Inserting at the Tail 1. Allocate a new node
2. Insert new element
3. Have new node point to null
head X Y 4. Have old last node point to new node
NULL
5. Update tail to point to new node
tail
new = malloc(sizeof(ELEMENT));
new Z new Z new->next = NULL;
NULL
tail new
Z tail = new;
head X Y
NULL
tail
Create a new node containing the data
Insertion into an ordered list Find the correct place in the list, and
newp N Link the new node at this place.
head A M P
newp = malloc(sizeof(ELEMENT));
prev ptr
head A M P
prev -> next = newp;
newp -> next = ptr;
prev ptr
35
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Removing the first node 1. Update head to point to next node
in the list
2. Free the former first node
head X Y
ptr = head;
ptr
X Y head = ptr->next;
ptr head
X Y free(ptr);
ptr head
1. Bring ptr to the second last node
Removing the Tail (last node) 2. Make ptr->next equal to NULL
3. Free tail
4. Make ptr the new tail
head X Y Z
NULL
ptr tail
ptr tail
Z free(tail);
head X Y
NULL NULL tail = ptr;
ptr tail
Steps:
Deletion from the middle of the list • Find the item (to be deleted) in the list
• Bring prev to the previous node
Item to delete: N • Link out node to be deleted, and
• Free up this node as free space.
head A M N P
head A M N P
prev ptr
What will happen if we did the following?
free(ptr);
prev->next = ptr->next;
else // check rest of list
Deletion function { prev = ptr;
ptr = ptr -> next;
// delete the item from ascending list
LINK delete_item(int val, LINK ptr) { // find node to delete
LINK prev, first; while (ptr != NULL && val > ptr->data) {
prev = ptr;
first = ptr; // remember start ptr = ptr -> next;
if (ptr == NULL) return NULL; }
else if (val == ptr -> data) if (ptr == NULL || val != ptr->data) {
{ // first node is to be deleted // NOT found in ascending list
ptr = ptr -> next; // second node return first; // original
first->next = NULL; }
free(first); // free up node else { // found, delete ptr node
return ptr; // 2nd node is new head prev -> next = ptr -> next;
} ptr->next = NULL;
The function is called as free(ptr); // free node
head = delete_item ( val, head ); return first; // original
where val is the value to be deleted. }}}
Search, print, and other operations
40
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR
Searching for a data element in a list
int Search( LINK head, int element) {
LINK temp;
Returns 1 if element is found,
0 otherwise
temp = head;
while (temp != NULL) {
if (temp -> data == element) return 1;
temp = temp -> next;
}
return 0;
}
Printing a list
void print_list (LINK head)
{
LINK temp;
temp = head;
We are dealing with the last element as a special case
while(temp!=NULL) since we want to print ‘END OF LIST” at the end.
{
if(temp->next ==NULL) printf("%d. END OF LIST \n", temp->data); // for the last element
else printf("%d -> ", temp->data); // for other elements
temp = temp->next;
}
}
Printing a list backwards
.
head
How can you print the elements of a list backwards when the links are in forward direction ?
Printing a list backwards – recursively
void PrintArray(LINK head) {
if(head -> next == NULL) { /* boundary condition to stop recursion */
printf(" %d, ",head -> data);
return;
}
PrintArray(head -> next); /* calling function recursively*/
printf(" %d, ",head -> data); /* Printing current element */
return;
}
Counting the number of nodes in a list
For each of the above, first create the linked list by reading in integers from the keyboard and
inserting one by one to an empty list
47
INDIAN INSTITUTE OF TECHNOLOGY KHARAGPUR