0% found this document useful (0 votes)
16 views47 pages

Linked Lists1

The document discusses abstract data types and linked lists. It defines an abstract data type as a specification of a set of data and operations that can be performed on the data, independent of implementation details. Linked lists are presented as a concrete implementation of lists using self-referential structures, where each node contains a data element and a pointer to the next node. Memory for linked lists is dynamically allocated by allocating each new node.

Uploaded by

Tapan Badhei
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)
16 views47 pages

Linked Lists1

The document discusses abstract data types and linked lists. It defines an abstract data type as a specification of a set of data and operations that can be performed on the data, independent of implementation details. Linked lists are presented as a concrete implementation of lists using self-referential structures, where each node contains a data element and a pointer to the next node. Memory for linked lists is dynamically allocated by allocating each new node.

Uploaded by

Tapan Badhei
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

Abstract Data Types and Linked Lists

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

Some examples follow.

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

void insert (set a, int x);


void delete (set a, int x);
int size (set a);
set union (set a, set b);
set intersect (set a, set b);
set minus (set a, set b); Function
prototypes

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

We shall later look into a concrete


way of implementing a stack

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

We shall later look into a concrete


way of implementing a queue

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

• Problems with arrays


• Size of an array should be specified beforehand (at least while dynamically allocating
memory).
• Deleting/Inserting an element requires shifting of elements.

Can we have some other implementation of Lists, to address these problems?

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 ;
};

The pointer variable next is called a link.


Each structure is linked to a succeeding structure by next.
Pictorial representation
A structure of type struct list struct list {
int data ;
struct list * next ;
};
data next

The pointer variable next contains either


• address of the location in memory of the successor list element
• or the special value NULL defined as 0.

NULL is used to denote the end of the list.

NULL
struct list a, b, c;

[Link] = 1; [Link] = 2; [Link] = 3;


[Link] = [Link] = [Link] = NULL;

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

What are the values of :


• [Link]->data 2
• [Link]->next->data 3
Linked Lists
A singly linked list is a concrete data
structure consisting of a sequence of nodes
next
Each node stores elem
• element
• link to the next node
node
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 D NULL
Header file : list.h Our own header file !!

#include <stdio.h> We can place this .h file in the same


directory as the .c source file, and
#include <stdlib.h> include the header file as
#include “list.h”
typedef char DATA;
// in our examples, we will store one char in each node; can be int, float, etc.
struct list {
DATA d;
struct list * next;
};
typedef struct list ELEMENT;
typedef ELEMENT* LINK;
Dynamic memory allocation: Review
typedef struct {
int hiTemp;
int loTemp;
double precip;
} WeatherData; int main ( ) {
int numdays;
WeatherData *days;
scanf (“%d”, &numdays) ;
days=(WeatherData *)malloc (sizeof(WeatherData)*numdays);
if (days == NULL) printf (“Insufficient memory\n”);
...
free (days) ;
}
Storage allocation
LINK head ;
Remember:
head = (LINK) malloc (sizeof(ELEMENT));
typedef struct list ELEMENT;
head->d = ‘n’; typedef ELEMENT* LINK;
head->next = NULL;

creates a single element list.

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;

A second element is added.

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;

We have a 3-element list pointed to by head.


The list ends when next has the sentinel value NULL.

head n e w NULL
Operations on Lists

(i) How to initialize such a self referential structure (LIST),


(ii) How to insert such a structure into the LIST,
(iii) How to delete elements from it,
(iv) How to search for an element in it,
(v) How to print it,
(vi) How to free the space occupied by the LIST?
Creating a list from scratch

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;

if (s[0] != ‘\0’) { head H


head = (LINK) malloc (sizeof(ELEMENT));
head->d = s[0];
tail = head; tail

for (i=1; s[i] != ‘\0’; i++) { head H


tail->next = (LINK) malloc(sizeof(ELEMENT));
tail = tail->next;
tail->d = s[i]; tail
}
tail->next = NULL;
} head H E
return head;
}
tail
Inserting a new element (node) into an existing list

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

new W new = malloc(sizeof(ELEMENT));

new W new-> next = head;

head X Y

new W head = new;

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

head X Y Z tail->next = new;


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

newp N We will ensure that the pointer prev is


always one element behind pointer ptr.
The new node is to be inserted
between prev and ptr
Insertion function LINK insert (int value, LINK ptr)
{ LINK newp, prev, first;
struct list { newp = create_node(value);
int data; if (ptr == NULL || value <= ptr -> data)
struct list * next; { // insert as new first node
}; newp -> next = ptr;
typedef struct list ELEMENT; return newp; // return pointer to first node
typedef ELEMENT * LINK; }
else { // insert in the middle (not first element)
LINK create_node(int val) first = ptr; // remember start
{ prev = ptr;
LINK newp; ptr = ptr-> next;
newp = (LINK) malloc (sizeof (ELEMENT)); while (ptr != NULL && value > ptr -> data)
newp -> data = val; { prev = ptr; ptr = ptr -> next; }
return (newp); prev -> next = newp; // link in
} newp -> next = ptr; //new node
The insert function is called as return first;
head = insert( val, head ); } We assume the list is kept sorted in
where val is the new value to be inserted } increasing order of data in each element.
Deleting an element (node) from an existing list

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

head X Y Z ptr->next = NULL;


NULL NULL

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

prev ptr prev->next = ptr->next;


free(ptr);

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

RECURSIVE APPROACH ITERATIVE APPROACH


int count (LINK head) { int count (LINK head) {
if (head == NULL) return 0; int cnt = 0;
for ( ; head != NULL; head=head->next)
return 1+count(head->next);
++cnt;
} return cnt;
}
Freeing all elements of a list
• In each iteration temp1 points at the head of the list and temp2 points at the second node.

void Free(ELEMENT *head) {


ELEMENT *temp1, *temp2;
temp1 = head; What will happen if we free the first
node of the list without placing a
while(temp1 != NULL) {
pointer on the second?
temp2 = temp1 -> next;
temp1->next = NULL;
free(temp1);
temp1 = temp2;
}
}
Practice Problems

1. Concatenate two lists (iteratively)


2. Reverse a list
3. Delete the maximum element from a list
4. Rotate the list by k positions counter-clockwise

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

You might also like