0% found this document useful (0 votes)
78 views53 pages

Programming & Data Structures: Pallab Dasgupta

The document discusses linked lists and their implementation using self-referential structures in C. It begins with an overview of linked lists and their benefits over arrays. It then demonstrates how to define a struct node with a data field and pointer to the next node. Examples are given to initialize a list, insert and delete nodes, search the list, print it in forward and backward order, and free the allocated memory. Key list operations like insertion, deletion and traversal are explained with code snippets. The document is intended as a teaching aid for introducing the concept of linked lists.

Uploaded by

Paras Dorle
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)
78 views53 pages

Programming & Data Structures: Pallab Dasgupta

The document discusses linked lists and their implementation using self-referential structures in C. It begins with an overview of linked lists and their benefits over arrays. It then demonstrates how to define a struct node with a data field and pointer to the next node. Examples are given to initialize a list, insert and delete nodes, search the list, print it in forward and backward order, and free the allocated memory. Key list operations like insertion, deletion and traversal are explained with code snippets. The document is intended as a teaching aid for introducing the concept of linked lists.

Uploaded by

Paras Dorle
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/ 53

Linked Lists

CS10001: Programming & Data Structures


Pallab Dasgupta
Dept. of Computer Sc. & Engg.,
Indian Institute of Technology
Kharagpur

Dept. of CSE, IIT KGP

Arrays: pluses and minuses


+ Fast element access.
-- Impossible to resize.
Many applications require resizing!
Required size not always immediately available.

Dept. of CSE, IIT KGP

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);
...
free (days) ;
}

Dept. of CSE, IIT KGP

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;
} ;
Dept. of CSE, IIT KGP

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.

Dept. of CSE, IIT KGP

Pictorial representation
A structure of type struct list

data next
The pointer variable next contains either
an 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.
Dept. of CSE, IIT KGP

struct list a, b, c;
a.data = 1;
b.data = 2;
c.data = 3;
a.next = b.next = c.next = NULL;
a

b
1

NULL

data next

Dept. of CSE, IIT KGP

c
2

NULL

data next

NULL

data next

Chaining these together

a.next = &b;
b.next = &c;
a

b
1

data next

c
2

data next

What are the values of :


a.next->data
a.next->next->data

Dept. of CSE, IIT KGP

NULL

data next
2
3

Linked Lists
A singly linked list is a
concrete data structure
consisting of a
sequence of nodes
Each node stores

next

element
link to the next node

node

elem

NULL

A
Dept. of CSE, IIT KGP

Linear Linked Lists


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
NULL

A
Dept. of CSE, IIT KGP

Header file : list.h


#include <stdio.h>
#include <stdlib.h>
typedef char DATA;
struct list {
DATA d;
struct list * next;
};
typedef struct list ELEMENT;
typedef ELEMENT * LINK;

Dept. of CSE, IIT KGP

Storage allocation
LINK head ;
head = malloc (sizeof(ELEMENT));
head->d = n;
head->next = NULL;

creates a single element list.


head

Dept. of CSE, IIT KGP

NULL

Storage allocation
head->next = malloc (sizeof(ELEMENT));
head->next->d = e;
head->next->next = NULL;

A second element is added.


head

Dept. of CSE, IIT KGP

NULL

Storage allocation
head->next->next = malloc (sizeof(ELEMENT));
head->next->next->d = w;
head->next->next-> = NULL;

We have a 3 element list pointed to by head.


The list ends when next has the sentinel value NULL.
head

Dept. of CSE, IIT KGP

NULL

List operations
List operations
(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?

Dept. of CSE, IIT KGP

Produce a list from a string


(recursive version)
#include list.h
LINK StrToList (char s[]) {
LINK head ;
if (s[0] == \0)
return NULL ;
else {
head = malloc (sizeof(ELEMENT));
head->d = s[0];
head->next = StrToList (s+1);
return head;
}
}
Dept. of CSE, IIT KGP

#include list.h
list from a string
LINK SToL (char s[]) {
(iterative version)
LINK head = NULL, tail;
int
i;
if (s[0] != \0) {
head = malloc (sizeof(ELEMENT));
head->d = s[0];
tail = head;
for (i=1; s[i] != \0; i++) {
tail->next = malloc(sizeof(ELEMENT));
tail = tail->next;
tail->d = s[i];
}
tail->next = NULL;
}
return head;
}
Dept. of CSE, IIT KGP

Inserting at the Head


1. Allocate a new node
2. Insert new element
3. Make new node point
to old head
4. Update head to point
to new node

Dept. of CSE, IIT KGP

Removing at the Head


1. Update head to point to
next node in the list
2. Allow garbage collector
to reclaim the former
first node

Dept. of CSE, IIT KGP

Inserting at the Tail


1. Allocate a new node
2. Insert new element
3. Have new node point
to null
4. Have old last node
point to new node
5. Update tail to point
to new node

Dept. of CSE, IIT KGP

Removing at the Tail


Removing at the tail of a
singly linked list cannot
be efficient!
There is no constanttime way to update the
tail to point to the
previous node

Dept. of CSE, IIT KGP

Insertion
To insert a data item into an ordered linked list involves:
creating a new node containing the data,
finding the correct place in the list, and
linking in the new node at this place.

Dept. of CSE, IIT KGP

Example of an Insertion
first

prev
3

new

ptr
8

Create new node for the 7


Find correct place when ptr finds the 8 (7 < 8)
Link in new node with previous (even if last) and ptr nodes
Also check insertion before first node!

Dept. of CSE, IIT KGP

12

Header file : list.h


#include <stdio.h>
#include <stdlib.h>
struct list {
int data;
struct list * next;
};
typedef struct list ELEMENT;
typedef ELEMENT * LINK;

Dept. of CSE, IIT KGP

Create_node function
Listpointer create_node(int data)
{
LINK new;
new = (LINK) malloc (sizeof (ELEMENT));
new -> data = data;
return (new);
}

Dept. of CSE, IIT KGP

insert function
LINK insert (int data, LINK ptr)
{
LINK new, prev, first;
new = create_node(data);
if (ptr == NULL || data < ptr -> value)
{
// insert as new first node
new -> next = ptr;
return new;
// return pointer to first node
}

Dept. of CSE, IIT KGP

else
{

// not first one

first = ptr; // remember start


prev = ptr;
ptr = ptr -> next; // second
while (ptr != NULL && data > ptr -> data)
{
// move along
prev = ptr;
ptr = ptr -> next;
}
prev -> next = new; // link in
new -> next = ptr; //new node
return first;
}
// end else
// end insert

Dept. of CSE, IIT KGP

Deletion
To delete a data item from a linked list involves
(assuming it occurs only once!):
finding the data item in the list, and
linking out this node, and
freeing up this node as free space.

Dept. of CSE, IIT KGP

Example of Deletion
first

prev
3

ptr
5

12

When ptr finds the item to be deleted, e.g. 8, we need


the previous node to make the link to the next one
after ptr (i.e. ptr -> next).
Also check whether first node is to be deleted.
Dept. of CSE, IIT KGP

// delete the item from ascending list


LINK delete_item(int data, LINK ptr) {
LINK prev, first;
first = ptr;
// remember start
if (ptr == NULL) {
return NULL;
}
else
if (data == ptr -> data) // first node
{
ptr = ptr -> next; // second node
free(first);
// free up node
return ptr;
// second
}
Dept. of CSE, IIT KGP

else
{

// check rest of list


prev = ptr;
ptr = ptr -> next;
// find node to delete
while (ptr != NULL && data > ptr->data)
{
prev = ptr;
ptr = ptr -> next;
}

Dept. of CSE, IIT KGP

if (ptr == NULL || data != ptr>data)


// NOT found in ascending
list
// nothing to delete
{
return first; // original
}
else
{

// found, delete ptr node


prev -> next = ptr -> next;
free(ptr);
// free node
return first; // original

}
}

}
// end delete

Dept. of CSE, IIT KGP

Representation with Dummy Node


head

dummy node
Insertion at the beginning is the same as insertion
after the dummy node

Dept. of CSE, IIT KGP

Initialization
head

Write a function that initializes LIST

typedef struct list {


int data;
struct list *next;
} ELEMENT;
ELEMENT* Initialize (int element) {
ELEMENT *head;
head = (ELEMENT *)calloc(1,sizeof(data)); /* Create initial node */

head->data = element; head -> next = NULL;


return head;
}
Dept. of CSE, IIT KGP

head

head

Dept. of CSE, IIT KGP

Insert

ELEMENT* Insert(ELEMENT *head, int element, int position) {


int i=0;
ELEMENT *temp, *new;
if (position < 0) {
printf("\nInvalid index %d\n", position);
return head;
}
temp = head;
for(i=0;i<position;i++){
temp=temp->next;
if(temp==NULL) {
printf("\nInvalid index %d\n", position);
return head;
}
}
new = (ELEMENT *)calloc(1,sizeof(ELEMENT));
new ->data = element;
new -> next = temp -> next;
temp -> next = new;
return head;
}
Dept. of CSE, IIT KGP

head

Delete

temp
head

temp

Dept. of CSE, IIT KGP

ELEMENT* Delete(data *head, int position) {


int i=0;data *temp,*hold;
if (position < 0) {
printf("\nInvalid index %d\n", position);
return head;
}
temp = head;
while ((i < position) && (temp -> next != NULL)) {
temp = temp -> next;
i++;
}
if (temp -> next == NULL) {
printf("\nInvalid index %d\n", position);
return head;
}
hold = temp -> next;
temp -> next = temp -> next -> next;
free(hold);
return head;
}
Dept. of CSE, IIT KGP

Searching a data element


int Search (ELEMENT *head, int element) {
int i; ELEMENT *temp;
i = 0;
temp = head -> next;
while (temp != NULL) {
if (temp -> x == element)
return TRUE;
temp = temp -> next;
i++;
}
return FALSE;
}
Dept. of CSE, IIT KGP

Printing the list


void Print (ELEMENT *head)
{
ELEMENT *temp;
temp = head -> next;
while (temp != NULL) {
printf("%d->", temp -> data);
temp = temp -> next;
}
}

Dept. of CSE, IIT KGP

Print the list backwards


.

head

How can you when the links are in forward direction ?


Can you apply recursion?

Dept. of CSE, IIT KGP

Print the list backwards


void PrintArray(ELEMENT *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 elemen
return;
}

Dept. of CSE, IIT KGP

head

Free the LIST

temp1

temp2

We can free temp1 only after we have retrieved the


address of the next element (temp2) from temp1.

Dept. of CSE, IIT KGP

Free the list


void Free(ELEMENT *head) {
ELEMENT *temp1, *temp2;
temp1 = head;
while(temp1 != NULL) /*boundary condition check*/
{
temp2 = temp1 -> next;
free(temp1);
temp1 = temp2;
}
}

Dept. of CSE, IIT KGP

1. A one-element list
head

4. after assigning NULL

head

tail

2. A second element is attached


head

tail
3. Updating the tail
head

Dept. of CSE, IIT KGP

B
tai
l

B NULL
tai
l

/* Count a list recursively */


int count (LINK head) {
if (head == NULL)
return 0;
return 1+count(head->next);
}

/* Count a list iteratively */


int count (LINK head) {
int cnt = 0;
for ( ; head != NULL; head=head->next)
++cnt;
return cnt;
}
Dept. of CSE, IIT KGP

/* Print a List */
void PrintList (LINK head) {
if (head == NULL)
printf (NULL) ;
else {
printf (%c --> , head->d) ;
PrintList (head->next);
}
}

Dept. of CSE, IIT KGP

/* Concatenate two Lists */

void concatenate (LINK ahead, LINK bhead) {


if (ahead->next == NULL)
ahead->next = bhead ;
else
concatenate (ahead->next, bhead);
}

Dept. of CSE, IIT KGP

Insertion

Insertion in a list takes a fixed amount of time once the position in


the list is found.

Before Insertion
p2

p1

A
q
B
Dept. of CSE, IIT KGP

Insertion
/* Inserting an element in a linked list. */
void insert (LINK p1, LINK p2, LINK q) {
p1->next = q;
q->next = p2;
}

After Insertion
p2

p1

A
q
B
Dept. of CSE, IIT KGP

Deletion
Before deletion

p
1

p->next = p->next->next;
p
1

Dept. of CSE, IIT KGP

garbage

After deletion
2

Deletion
Before deletion

q = p->next;
p->next = p->next->next;
p

After deletion
1

2
q

Dept. of CSE, IIT KGP

3
free (q) ;

Delete a list and free memory


/* Recursive deletion of a list */
void delete_list (LINK head) {
if (head != NULL) {
delete_list (head->next) ;
free (head) ; /* Release storage */
}

Dept. of CSE, IIT KGP

You might also like