0% found this document useful (0 votes)
26 views

Linked Lists

Linked list data structure

Uploaded by

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

Linked Lists

Linked list data structure

Uploaded by

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

Linked Lists

 A linear collection of self-referential objects,


called nodes, connected by links
 linear: for every node in the list, there is one and only
one node that precedes it (except for possibly the first
node, which may have no predecessor,) and there is
one and only one node that succeeds it, (except for
possibly the last node, which may have no successor)
 self-referential: a node that has the ability to refer to
another node of the same type, or even to refer to itself
 node: contains data of any type, including a reference
to another node of the same data type, or to nodes of
different data types
 Usually a list will have a beginning and an end; the first
element in the list is accessed by a reference to that
class, and the last node in the list will have a reference
that is set to null
Linked Lists
A B C 

Head
 A linked list is a linear collection of connected nodes
 Each node contains at least
 A piece of data (any type) node
 Pointer to the next node in the list
A
 Head: pointer to the first node
 The last node points to NULL data pointer

a1 a2 a3 a4

Memory
Content a1 800 a2 712 a3 992 a4 0

Memory
1000 800 3 712 992
Address
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).
head tail

struct Node struct Node struct Node


{ char { char { char
NULL
element;
Node *next;
*next; element;
Node *next;
*next; element;
Node *next;
*next;
}; }; };
Composition of a Linked List

The pointers play a big role in maintaining


the linked list. The nodes in a linked list
can be spread out over memory.
Therefore, it is not possible to calculate
the address of the next node, like it is
possible to calculate the next element of
an array. If a pointer from one node to
another is lost, the list from that point is
lost forever. Therefore, extreme care
should be taken when assigning or re-
assigning a pointer in a linked list.
Composition of a Linked List

D
A

B E
head
C

If the pointer between any nodes (say B and C) is re-assigned erroneously to


null or anything else, the access to the rest of the nodes ( C, D and E ) is then
lost.
If you loose the head pointer, you loose the entire list.
Linked Representation of Data
 In a linked representation, data is
not stored in a contiguous 358 797
manner. Instead, data is stored 561 501 724
at random locations and the 345
current data location provides 555 490 701
the information regarding the 513
location of the next data.
358 797
561 501
345 724
Adding item 498 on to the linked list
555 490 701 513
498
Deleting item 358 from the linked list 358 797
561 501
345 724

555 490 701 513


498
Advantages of Linked Lists
over Arrays
Linked lists are more complex to code and manage than
arrays, but they have some distinct advantages.

a) A linked list can easily grow and shrink in size -


The programmer doesn’t need to know how many
nodes will be in the list. They are created in
memory as needed.
b) Speed of insertion or deletion from the list -
Inserting and deleting elements into and out of
arrays requires moving elements of the array. When
a node is inserted, or deleted from a linked list, none
of the other nodes have to be moved.
Creating a Linked List

Just like any other data type, the information about the
node
has to be first be declared.

Step 1) Declare a data structure for the nodes.

struct Node
{
int data;
struct Node *next;
};

Typedef struct Node *NODEPTR;


Creating a Linked List
a)In this example, the first member of the Node
holds the node’s data. This could just as well be
just a string, or a structure of student records.

b)The second member is a pointer called next. It


holds the address of any object that is a structure
of type Node. Hence each Node struct can point
to the next node in the list.

The Node struct contains a pointer to an object of the


same type as that being declared. It is called a self-
referential data structure. This makes it possible to
create nodes that point to other nodes of the same
type.
Creating a Linked List
Next, since there is no physical relationship between
nodes, a pointer needs to be created to point to the first
logical node in the list.

Step 2) Declare a pointer to serve as the head of the


list:
NODEPTR head = NULL;

Once we have done these 2 steps (i.e. declared a node


data structure, and created a NULL head pointer, we
have an empty linked list.

head null
Creating a Linked List
 Step 3) Allocate memory for the
node

head = (NODEPTR) /*type casting */


malloc(sizeof(struct node));

head 100 100 ?

?
Creating a Linked List

 Note : head is not a node. It is a simple pointer


to a node. head used to "maintain" start of list
 To assign values to data items in first node we
have following statement:
(*head).data = 12;
 head is a pointer variable so *head is the node
that head points to
 The parentheses are necessary because the
dot operator . has higher precedence than the
dereference operator *
Creating a Linked List

 The arrow operator -> combines the actions


of the dereferencing operator * and the
dot operator to specify a member of a struct
or object pointed to by a pointer
 (*head).data= 12;
can be written as
head->data= 12;
 The arrow operator is more
commonly used
 head->next = NULL;
Creating a Linked List

 The Linked list containing a single node can


be visualised as
100
head 100 12

0
100
Sample Linked List Operations
void main() {
NODEPTR ListStart = NULL;
/* safest to give ListStart an initial legal
value -- NULL indicates empty list */
Pictorially In Memory
ListStart ListStart
0
100

ListStart = (NODEPTR) malloc(sizeof(struct node));


/* ListStart points to memory allocated at
location 108 */
ListStart ListStart Data Next
? ? 108 ? ?
Data Next 100 108
Sample Linked List Ops (cont)
ListStart->data = 5;
ListStart ListStart
5 ? 108 5 ?
100 108

ListStart->next = NULL;
ListStart ListStart
5 108 5 0
100

108
ListStart->next
5 ? ?
= (NODEPTR) 108
malloc(sizeof(struct
5 120 ? ?
node));
ListStart ListStart
100 108 120

ListStart->next->data = 9;
ListStart->next->next = NULL;
ListStart ListStart
5 9 108 5 120 9 0
100 108 120
Sample Linked List Ops (cont)
ListStart->next->next = (NODEPTR) malloc(sizeof(struct node));
ListStart ListStart
5 9 ? ? 108 5 120 9 132 ? ?
100 108 120 132
ListStart->next->next->data = 6;
ListStart->next->next->next = NULL;
ListStart ListStart
5 9 6 108 5 120 9 132 6 0
100

108

120

132

/* Linked list of 3 elements (count data values):


ListStart points to first element
Basic Operations on a Linked
List
1. Traverse (walk) the list.
2. Add a node.
3. Delete a node.
4. Search for a node.
Displaying the contents of a
linked list
 A traverse operation visits each node in
the linked list
 A pointer variable cur keeps track of the
current node
for (Struct Node *cur = head;
cur != NULL; cur = cur-
>next)
printf(“%d”, cur->data);
A few questions on linked lists
 Write a function to count the nodes of a linked list.
 int get_count(NODEPTR head)
A few questions on linked lists
 Write a function to count the nodes of a linked list.
 int get_count(NODEPTR head)

int count_list(NODEPTR head)


{
int count;
for(count=0; head != NULL; head=head->next, count++);
return(count);
}
A few questions on linked lists
 Write a function to find the value stored in nth node of a
linked list.
 int get_nth(NODEPTR head, int n)
 Where n=1 means first node
A few questions on linked lists
 Write a function to find the value stored in nth node of a
linked list.
 int get_nth(NODEPTR head, int n)
 Where n=1 means first node
int get_nth(NODEPTR head, int n)
{
int count;
for(count=1; head != NULL && count!=n ; head=head->next, count+
+);
if(head)
return(head->data);
else return(0);
}
A few questions on linked lists
 Write a function to display the value of an
median ordered linked list.
 int get_median(NODEPTR head)
A few questions on linked lists
 Write a function to find the value stored in nth node from
end of a linked list.
 int get_end_nth(NODEPTR head, int n)
 Where n=0 means last node
A few questions on linked lists
 Write a function to display the value of an
median ordered linked list.
 int get_median(NODEPTR head)

int get_median(NODEPTR head)


{
int count = count_list(head);
int m1, m2;
if(count%2)
return(get_nth(head, 1+count/2));
m1 = get_nth(head, count/2);
m2 = get_nth(head, 1+
(count/2)); return ((m1+m2)/2);
}
A few questions on linked lists
 Write a function to find the value stored in nth node from
end of a linked list.
int get_end_nth(NODEPTR head, int n)
{
int count;
NODEPTR p1=head, p2=head;
for(count=0; p1 != NULL && count!=n ; p1=p1->next, count+
+); while(p1 && p1->next)
{
p1=p1->next;
p2=p2->next;
}
if(p2)
return(p2->data);
else return(0);
}
Adding Nodes to a Linked List
There are four steps to add a node to a linked
list:

 Allocate memory for the new node.


 Determine the insertion point you need to
know only the new node’s predecessor
(pPre)
 Point the new node to successor of pPre.
 Point pPre to the new node.
Inserting a Node at the Front

Head f g h next NULL


next next

e NEXT
newNode
Inserting a Node at the Front
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

We want to add a new entry,


13, to the front of the linked
list shown here.
15

10

7
13
null
entry
head
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

Create a new node,


pointed to by a local temp_ptr

variable temp_ptr.
15

10

7
13
null
entry
head
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

temp_ptr = (NODEPTR)
malloc(sizeof(struct node)); temp_ptr

15

10

7
13
null
entry
head
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

temp_ptr = (NODEPTR)
malloc(sizeof(struct node)); 13
temp_ptr

Place the data in the new


node's data_field. 15

temp_ptr->data = 13;
10

7
13
null
entry
head
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

temp_ptr = (NODEPTR)
malloc(sizeof(struct node)); temp_ptr
13
Place the data in the new node's
data_field.
15
Connect the new node to the front
of the list. 10
temp_ptr->next = *head;
7
13
null
entry
head
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

temp_ptr = (NODEPTR)
malloc(sizeof(struct node)); temp_ptr
13
Make the old head pointer
point to the new node.
15

10

7
13
null
entry
head
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

temp_ptr = (NODEPTR)
malloc(sizeof(struct node)); temp_ptr
13
*head = temp_ptr;
15

10

7
13
null
entry
head
Inserting a Node at the Front
void insert_start(NODEPTR *head, int x);

temp_ptr = (NODEPTR) malloc(sizeof(struct


node));
13
*head = temp_ptr;
15
When the function returns,
the linked list has a new 10
node at the front. 7
null
head
void insert_start(NODEPTR *head, int x)
{
NODEPTR temp_ptr = (NODEPTR) malloc(sizeof(struct
node)); temp_ptr->data = x;
temp_ptr->next = *head;
*head = temp_ptr;
}
Lost Nodes Pitfall

Linked list before insertion Situation after executing


head = (NODEPTR) malloc(sizeof(struct node));
head->data=12;
Inserting a Node into a Specified
Position of a Linked List

 To insert a node between two nodes


newPtr->next = cur;
prev->next = newPtr;
Inserting element in middle

A0 A1 A2

head after_me

At any point, we can add a new item x by doing this:

temp_ptr = (NODEPTR) malloc(sizeof(struct node));


temp_ptr->data = x;
temp_ptr->next = after_me->next;
after_me->next = temp_ptr;
Inserting element in middle

A0 A1 A2

head after_me

tmp_ptr

At any point, we can add a new item x by doing


this:
temp_ptr = (NODEPTR) malloc(sizeof(struct node));
temp_ptr->data = x;
temp_ptr->next = after_me->next;
after_me->next = temp_ptr;
Inserting element in middle

A0 A1 A2

head after_me x

tmp_ptr

At any point, we can add a new item x by doing


this:

temp_ptr->data
temp_ptr = x;
= (NODEPTR) malloc(sizeof(struct
node));
temp_ptr->next = after_me->next;
after_me->next = temp_ptr;
Inserting element in middle

A0 A1 A2

head after_me x

tmp_ptr
At any point, we can add a new item x by doing
this:

temp_ptr = (NODEPTR) malloc(sizeof(struct node));


temp_ptr->data x;
temp_ptr->next = after_me->next;
after_me->next = temp_ptr;
Inserting element in middle

A0 A1 A2

head after_me x

tmp_ptr
At any point, we can add a new item x by doing this:
temp_ptr = (NODEPTR) malloc(sizeof(struct node));
temp_ptr->data = x;
temp_ptr->next = after_me->next;
after_me->next = temp_ptr;
void insert_after(NODEPTR after_me, int x)
{
NODEPTR temp_ptr = (NODEPTR) malloc(sizeof(struct node));
temp_ptr ->data = x;
temp_ptr ->next = after_me->next;
after_me->next = temp_ptr;
}
Adding a node to a sorted list
You are given a linked list in which the elements
are ordered. You want to add a node with a
new element, but you want to keep the list still
ordered.
To do so, you have to spot the place to insert the
new node by traversing the list. Here, there are
some cases to consider:
 What if the list is empty?
 What if I need to add a node before the beginning of the list?
 What if I need to add a node somewhere inside the list?
 Caution you cannot go back!
 What if I need to add a node at the end of the list?
Adding a node to a sorted list

Create a new node.


Store data in the new node.
if there are no nodes in the list or new value smaller than value
in first node
Make the new node the first node.
else
Find the first node whose value is greater than or equal
the new value, or the end of the list (whichever is
first). Insert the new node before the found node, or at
end of the list if no node was found.
endif
Adding a node to a sorted list
(Program)
main()
{
NODEPTR head = NULL, p,
prev; int i;

scanf("%d" ,&i);
insert_start(&head, i);
scanf("%d", &i);
while (i)
{
if(head->data>i) insert_start(&head,
i); else
{
for(p=head; p!=NULL; prev=p, p=p->next)
if(p->data > i) {insert_after(prev, i);
break;} if(p==NULL) insert_after(prev, i);
}
scanf("%d", &i);
}
}
Adding a node to a sorted list
(Program)
main()
{
NODEPTR head = NULL, p,
prev; int i;

scanf("%d", &i);
while (i)
{
for(prev = NULL, p= head; (p != NULL)&& > p->data);
(i prev = p, p = p->next);
if(prev==NULL)
insert_start(&head,
i);
else
insert_after(prev, i);
scanf("%d", &i);
}
}
A few questions on linked lists
 Write a function to merge two ordered lists into a
third list.
 void merge_sorted(NODEPTR head1,
NODEPTR head2, NODEPTR *head3)
void merge_sorted(NODEPTR head1, NODEPTR head2, NODEPTR *head3)
{
NODEPTR temp1=head1, temp2=head2, end1=NULL, end2;
*head3 = NULL;
while(temp1 && temp2){
if(temp1->data
< temp2->data)
{
if(*hea
d3==NUL
L)
{
i
n
s
e
r
t
_
s
t
a
r
t
(
&
e
n
else
{
insert_after(end1, temp2->data);
end1 = end1->next;
}
temp2 = temp2->next;
}
}
while(temp1)
{
insert_after(end1, temp1->data);
temp1 = temp1->next;
end1 = end1->next;
}
while(temp2)
{
insert_after(end1, temp2->data);
temp2 = temp2->next;
end1 = end1->next;
}
}
Interview Question
 How can you find the value in mid of a linked
list in a single scan?
A few questions on linked lists
 Write a function to split a linked list in middle into two. If
odd number of nodes are there then first list to have one
more node than second list.
 void split_list(NODEPTR head, NODEPTR *head1)
A few questions on linked lists
 Write a function to split a linked list in middle into two. If
odd number of nodes are there then first list to have one
more node than second list.
void split_list(NODEPTR head, NODEPTR *head1)
{
NODEPTR p1=head, p2=head;
while(p2)
{
if(p2)
p2=p2-
>next;
if(p2)
p2=p2-
>next;
if(p2)
p1=p1-
>next;
}
*head1 = p1->next;
A few questions on linked lists
 Print a singly-linked list backwards with and without
recursion.
 Write a C program to copy a linked list.
 Reorder A->B->C->D->E as B->A->D->C->E in a singly
linked list
 Write a function to return the Nth-to-Last element in a
singly linked list of unknown length. If N = 0, then your
function must return the last element.
 Write a function to reverse a Linked-list
 How would you find a loop in a singly-linked list?
 Find the middle element in a singly linked list without
counting the number of elements.
A few questions on linked lists
 Given an integer linked list of which both first half and
second half are sorted independently. Write a function to
merge the two parts to create one single sorted linked
list in place [do not use any extra space].
 Sample test case:
 Input 1 :1->2->3->4->5->1->2; Output: 1->1->2->2->3->4->5
 Input 2: 1->5->7->9->11->2->4->6; Output 2: 1->2->4->5->6->7-
>9->11
 Given two linked lists, return the intersection of the two
lists: i.e. return a list containing only the elements that
occur in both of the input lists.
A few questions on linked lists
 Write a function that returns the intersection of the two
ordered lists: i.e. return a list containing only the
elements that occur in both of the input lists.
 void intersect_list(NODEPTR head1, NODEPTR head2,
NODEPTR *head3)
void intersect_list(NODEPTR head1, NODEPTR head2, NODEPTR *head3)
{
NODEPTR temp1=head1, temp2=head2, end1=NULL, end2;
*head3 = NULL;
while(temp1 && temp2)
{
if(temp1-
>data ==
temp2->data)
{
if(*he
ad3==N
ULL)
{
i
n
s
e
r
t
_
s
t
a
r
t
(
&
A few questions on linked lists
 Write a function that returns the intersection of the two
unordered lists: i.e. return a list containing only the
elements that occur in both of the input lists.
void intersect_list1(NODEPTR head1, NODEPTR head2, NODEPTR
*head3)
{
NODEPTR temp1=head1, temp2=head2, end1=NULL;
*head3 = NULL;
while(temp1)
{
if(sear
ch_list
(temp2,
temp1-
>data))
{
i
f
(
*
h
e
a
d
3
=
=
N
A few questions on linked lists
 Write a function to reverse a Linked-list
Reversing linked list
NODEPTR reverse(NODEPTR head)
{
NODEPTR previous = NULL;
NODEPTR current = head;
NODEPTR forward;

while (current != NULL)


{
forward = current->next;
current->next = previous;
previous = current;
current = forward;
}
return previous;
}
Deleting a Node from a Linked List

 Deleting a node requires that we logically remove the


node from the list by changing various links and then
physically deleting the node from the list (i.e., return it
to the heap).
 Any node in the list can be deleted. Note that if the
only node in the list is to be deleted, an empty list will
result. In this case the head pointer will be set to
NULL.
 To logically delete a node:
 First locate the node itself (pCur) and its logical predecessor
(pPre).
 Change the predecessor’s link field to point to the deleted
node’s successor (located at pCur -> next).
 Recycle the node using the free() or delete function.
Deleting the First Node from a Linked List
Before: Code:
Head = pCur - next;
>
Head 75 124 free(pCur);

pPre pCur

After:

Head Recycle 124


d

pPre pCur

68
Deleting a Node from a Linked Li st – General
Case
Before: Code:
pPre -> next = -> next;
pCur
75 96 124
free(pCur);

pPre pCur

After:

Recycle
75 d 124

pPre pCur
Deleting a Node From Start of Linked List

int delete_start(Node **p)


{
int i;
Node *q;
if(*p==NULL)return 0;
i = (*p)->data;
q = (*p)->next;
delete *p;
*p = q;
cout << "\nValue deleted” <<
i; return i;
}
Deleting a Node From a Linked List

int delete_after(Node *p)


{
int i;
Node *q;
if(p==NU
LL)retur
n 0;
if(p->next==NULL) return 0;
q = p->next;
p->next = p->next->next;
i = q->data;
delete q;
cout << "\nValue deleted” <<
i; return i;
A few questions on linked lists
 Write a function to delete all nodes of a linked list
A few questions on linked lists
 Write a function to delete all nodes of a linked list

void delete_list(Node **list)


{
while(*list)
delete_start(list);
}
A few questions on linked lists
 Write a function to remove alternate nodes from a given
linked list
A few questions on linked lists
 Write a function to remove alternate nodes from a given
linked list
void delete_alternate(Node *list)
{
Node *p=list;

while(p!=NULL && p->next != NULL)


{
delete_after(p);
p=p->next;
}
}
A few questions on linked lists
 Write a function to delete all nodes containing
given
value
void delete_all_val(Node **list, int val)
A few questions on linked lists
 Write a function to delete all nodes containing
given value
void delete_all_val(Node **list, int val)
{
Node *p=*list;
while(*list != NULL && (*list)->data == val)
delete_start(list);
p=*list;
while(p!=NULL && p->next != NULL)
{
if(p->next->data == val)
delete_after(p);
else p=p->next;
}
}
A few questions on linked lists
 Write a function to delete all duplicates in a linked list
A few questions on linked lists
 Write a function to delete all duplicates in a linked list

void remove_duplicate(Node **list)


{
Node *p=*list, *q;
while(p->next!=NULL)
{
q = p->next;
delete_all_val(&q, p->data);
p->next = q;
p=p->next;
}
}
Programming Assignment

Write a program to implement maintaining of friends'


list. Each person will have his own list of friends and
give options to user to:
1. Add a new person in list
2. Delete person in list
3.Add a friend to existing person (Max friends
allowed 10 say)
4. Delete friend from existing person
5. Display all friends of any person
6. Display common friends of any two persons
7. Tell if two persons are friends of each other
8. Suggest friends
Programming Assignment
 Remove in a linked list all the nodes that have a greater
value to their right.
 Input:
10 -> 12 -> 15 -> 20 -> 5 -> 16 -> 25 -> 8 -> NULL
10 -> 12 -> 15 -> 20 -> 25 -> 26 -> 30 -> 40 -> NULL
20 -> 18 -> 15 -> 10 -> 8 -> 6 -> 5 -> 3 -> NULL
 Output:
20 -> 25 -> 8 -> NULL
40 -> NULL
20 -> 18 -> 15 -> 10 -> 8 -> 6 -> 5 -> 3 -> NULL
Circular Linked Lists
 A Circular Linked List is a special type of
Linked List. No node contains NULL
 It supports traversing from the end of the list
to the beginning by making the last node point
back to the head of the list
 A Rear pointer is often used instead of a Head
pointer (Why?)
Circular Linked List Definition

struct Node{
int data;
struct Node
*next;
};
typedef
struct Node
*NODEPTR;
Circular Linked List
Operations

 print(NODEPTR Rear)
//print the Circular Linked List
once

 insertNode(NODEPTR Rear, int item)


//add new node to ordered
circular linked list

 deleteNode(NODEPTR Rear, int item)


//remove a node from circular
Traverse the list
void print(NODEPTR Rear)
Traverse the list
void print(NODEPTR Rear){
NODEPTR Cur;
if(Rear != NULL)
{ Cur = Rear-
>next;
do{
count << curr->data;
Cur = Cur->next;
}while(Cur != Rear->next);
}
}
10 20 40 55 70

Rear
Insert Node
 Insert into an empty list
NODEPTR p = new
Node;

p->data = 10;
Rear = p;
Rear->next = Rear; 10

New Rear
 Insert to head of a Circular Linked List
p>next = Rear->next;
Rear->next = p;

10 20 40 55 70

New Head
Rear
 Insert to end of a Circular Linked List
p->next = Rear->next;
Rear->next = p;
Rear = p;

10 20 40 55 70

Cur New
Rear
 Insert to middle of a Circular Linked List
between Prev and Cur
p>next = Cur;
Prev->next = p;

10 20 55 70

40
Prev Cur Rear

New
 Delete a node from a single-node Circular
Linked List
Rear = NULL;
delete Cur;

10

Rear = Cur = Prev


Delete Node
 Delete the head node from a Circular Linked
List
Cur = Rear->next;
Rear->next = Cur->next;
Delete Cur;

10 20 40 55 70

Cur Rear Prev


 Delete the end node from a Circular Linked
List Prev->next = Rear->next;
Delete Cur;
Rear = Prev;

10 20 40 55 70

Prev Cur
Rear
 Delete a middle node Cur from a
Circular Linked List
Prev->next = Cur->next;
Delete Cur;

10 20 40 55 70

Prev Cur Rear


A few questions on linked lists
 Write a function to convert singly linked list to
circular linked list.

single_to_circular(NODEPTR *list)
A few questions on linked lists
 Write a function to convert singly linked list to
circular linked list.

void single_to_circular(NODEPTR *list)


{
NODEPTR p=*list;
if(p==NULL) return;
while(p->next)
p = p->next;
p->next = *list;
*list = p;
}
Applications of singly linked
lists
 Implementing Stacks
 Polynomials
 Sparse arrays
 File Allocation Table
 Big numbers
Implementation of Stacks
using linked lists

push = insert_start(&list);
Pop = delete_start(&list);
Implementation of Queues
using linked lists

Enqueue = insert_end(&rear);
Dequeue = delete_start(&rear);
Polynomial Application
 Many high level polynomials have many
terms with a 0 coefficient.
 Would need to store them if using an
array.
 Use a linked list to not take memory for items
with a 0 coefficient.
Polynomials
A( x )  am  1 xe  am  2 x e
...a0 x e0
m 1 m  2

Representation
typedef struct poly_node *poly_pointer;
typedef struct poly_node
{ int coef;
int expon;
poly_pointer next;
};
poly_pointer a, b, c;

coef expon link


Example

a  3x 1 4  2 x 8  1
a
3 14 2 8 1 0 null

b  8x 1 4  3x 1 0  1 0 x 6
b
8 14 -3 10 10 6 null
Adding Polynomials
3 14 2 8 1 0
a
8 14 -3 10 10 6
b
11 14 a->expon == b->expon
d

3 14 2 8 1 0
a
8 14 -3 10 10 6
b
11 14 -3 10 a->expon < b->expon
d
Adding Polynomials (cont’d)

3 14 2 8 1 0
a
8 14 -3 10 10 6
b
11 14 -3 10 2 8
d
a->expon > b->expon
About sparse arrays
 A sparse array is simply an array most of whose entries
are zero (or null, or some other default value)
 For example: Suppose you wanted a 2-dimensional
array of course grades, whose rows are students and
whose columns are courses
 There are about 22,000 students
 There are about 5000 courses
 This array would have about 11,00,00,000 entries
 Since most students take fewer than 5000 courses, there will
be
a lot of empty spaces in this array
 This is a big array, even by modern standards
 There are ways to represent sparse arrays efficiently
Sparse arrays as linked lists
 We will start with sparse one-dimensional arrays, which
are simpler
 We’ll do sparse two-dimensional arrays later
 Here is an example of a sparse one-dimensional array:
0 1 2 3 4 5 6 7 8 9 10
0 0 0 110 17 0 0 23 14 0 0 0
ary

 Here is how it could be represented as a linked list:


ary
4 17 7 23 8 14
Sparse two-dimensional arrays
 Here is an example of a sparse two-dimensional array, and
how it can be represented as an array of linked lists:
0 1 2 3 4 5
0 12 0 5 12
1 1
2 2
3 8 33 3 1 8 5 33
4 17 4 3 17
5 5

 With this representation,


 It is efficient to step through all the elements of a row
 It is expensive to step through all the elements of a column
 Clearly, we could link columns instead of rows
 Why not both?
Another implementation
 If we want efficient access to both rows and
columns, we need another array and additional data
0 1 2 3 4 5
in each node cols
0 1 2 3 4 5
0 12 rows
1 0 0 5 12
2 1
3 8 33 2
4 17 3 3 5 33
3 1 8
5 4 4 3 17
5
 Do we really need the row and column number in
each node?
Yet another implementation
 Instead of arrays of pointers to rows and 0 1 2 3 4 5
0 12
columns,
1
you can use linked lists:
2
cols 1 3
3 8 33
4 17
5
rows 5
0 0 5 12
 This may be the
best
3 5 33 implementation if
3 3 1 8 most rows and
most columns
4 4 3 17 are totally empty
Multiply matrices
for(i=0 ; i<Row1 ; i++)
{
for(j=0 ; j<Column2 ; j++)
{
Mp[i][j] = 0 ;
for(k=0 ; k<Row2 ; k++)
{
Mp[i][j] = Mp[i][j] + ( Matrix A[i][k] * Matrix B[k][j] );
}
}
}
Single Linked List Application
 File Allocation Table
(FAT)
directory entry  FAT has an entry for each
name start block disk block.
test 217
 FAT entries rather than
0
blocks themselves are
linked.
217 618
 Example:
 MS-DOS and OS/2
339 EOF
217  Merit:
339  Save disk block

618 339 space


618  Faster random
accesses
#blocks -1  Demerit:
FAT  A significant number of
disk head seeks
Big Numbers
 The unsigned int type in C requires 4 bytes of
memory storage. With 4 bytes we can store
integers as large as 232-1; but what if we need
bigger integers, for example ones having
hundreds of digits?
 One way of dealing with this is to use a different
storage structure for integers, such as an array
of digits. If we represent an integer as an array
of digits, where each digit is stored in a different
array index.
 But if we want the integers to be as large as we
like, the best data structure will be linked list,
where each node holds one digit.
A few examples of big number
 Googol
A few examples of big number
 A googol equals 10100.
 In decimal notation, it is written as the digit 1
followed by one hundred 0s:
 10000000000000000000000000000000000
0
00000000000000000000000000000000000
0
00000000000000000000000000000.
 Roughly equals 70! (factorial of 70)
A few examples of big number
 Factorial of 10,000.
A few examples of big number
 Factorial of 10,000 is 35,659 digits long
A few examples of big number
 Find the largest prime number
A few examples of big number
 Find the largest prime number
 As of January 2016, the largest known
prime number is 274,207,281 − 1, a number
with 2,23,38,618 digits.
Big Numbers
 To allow for arbitrary large numbers, use a
linked list where each holds one digit.
 This is good conceptually, but for efficiency, we
can use an int to hold several digits per node.
 Similarly, we can use a linked list for a string
of arbitrary length.
Add two big numbers
Add two big numbers
Circular List Application
 Round-Robin Based Job Scheduling
head

Process ID Process ID Process ID Process ID


100 105 99 217
Prog name Prog name Prog name Prog name
“emacs” “g++” “a.out” “ps2pdf”
CPU CPU CPU CPU
Registers Registers Registers Registers
Page Page Page Page
Table Table Table Table
File File File File
Descriptors Descriptors Descriptors Descriptors
Josephus Problem
 Given a group of n men arranged in a circle
under the edict that every mth man will be
executed going around the circle until only
one remains, find the position in which you
should stand in order to be the last survivor.
Josephus Problem - Example
M=3, N=5

Initial state: Round 1 Round 2

0 0 0 0
4 1 4 1 4 1 4 X
1
3 2 3 X
3 2 X 2
3 2

Person removed so far: {2, 0,


Josephus Problem - Example
M=3, N=5

Round 3 Round 2
X X X
0 0
X
0 X 0
X
4 1 4 1 X4 1 4
1 X
3 2
X 3 2 X 3 2 X 3 2 X

Person removed so far: {2, 0, 4, 1 } Survivor is 3


OriginalJosephus Problem
 The original Josephus problem consisted of a
circle of 41 men with every third man killed.In
order for the lives of the last two men to be
spared, they must be placed at positions 31
(last) and 16 (second-to-last). The complete
list in order of execution is 3, 6, 9, 12, 15, 18,
21, 24, 27, 30, 33, 36, 39, 1, 5, 10, 14, 19,
23, 28, 32, 37, 41, 7, 13, 20, 26, 34, 40, 8,
17, 29, 38, 11, 25, 2, 22, 4, 35, 16, 31.
Original Josephus Problem
Josephus Problem - Solution

while(list->next!=list)
{
for(i=0; i<count-1; i++)
list = list->next;
delete_after(list);
}
Array of linked lists
 An array of linked list combines a static structure (an
array) and a dynamic structure (linked lists) to form
a useful data structure. This type of a structure is
appropriate for applications, where say for example,
number of categories is known in advance, but how
many nodes in each category is not known. For
example, we can use an array (of size 26) of linked
lists, where each list contains words starting with a
specific letter in the alphabet.
Variations of Linked Lists
 Doubly linked lists
 Each node points to not only successor but the
predecessor
 There are two NULL: at the first and last nodes
in the list
 Advantage: given a node, it is easy to visit its
predecessor. Convenient to traverse lists
backwA
ards B C 

Head
Advantages of Doubly Linked
Lists
 Solves the problem of traversing backwards in
an ordinary linked list.(Implementing big
numbers)
 A link to the previous item as well as to the
next item is maintained.
 The only disadvantage is that every time an
item is inserted or deleted, two links have to be
changed instead of one.
Doubly Linked List Definition

struct Node{
int data;
struct Node
*next,
*prev;
};
typedef
struct Node
*NODEPTR;
Inserting into a Doubly Linked List

a c

head tail
current

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


newNode->prev = current;
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Inserting into a Doubly Linked List

a c

head b tail
current

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


newNode->prev = current;
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Inserting into a Doubly Linked List

a c

head b tail
current

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


newNode->prev = current;
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Inserting into a Doubly Linked List

a c

head b tail
current

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


newNode->prev = current;
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Inserting into a Doubly Linked List

a c

head b tail
current

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


newNode->prev = current;
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Inserting into a Doubly Linked List

a c

head b tail
current

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


newNode->prev = current;
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Inserting into a Doubly Linked List

a c

head b tail
current

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


newNode->prev = current;
newNode->next = current->next;
newNode->prev->next = newNode;
newNode->next->prev = newNode;
current = newNode;
Inserting into a Doubly Linked List
Take care of all cases
Write code for
 Insert_start(NODE
PTR *head, int val)
 Insert_end(NODEP
TR head, int val);
Inserting at start of doubly
linked list
Insert_start(NODEPTR *head, int val)
{
NODEPTR a = (NODEPTR) malloc(sizeof(struct
node));
a->data = val;
if(*head==NULL)
{
a->prev=a->next=NULL;
*head = a;
return;
}
a->prev=NULL;
a->next=*head;
(*head)->prev
= a;
*head = a;
Deleting an element from a double
linked list

a c

head b
current

oldNode=current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
current = oldNode->prev;
free(oldNode);
Deleting an element from a double
linked list

a c

head b
current
oldNode

oldNode=current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
current = oldNode->prev;
free(oldNode);
Deleting an element from a double
linked list

a c

head b
current
oldNode

oldNode=current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
current = oldNode->prev;
free(oldNode);
Deleting an element from a double
linked list

a c

head b
current
oldNode

oldNode=current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
current = oldNode->prev;
free(oldNode);
Deleting an element from a double
linked list

a c

head b
current
oldNode

oldNode=current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
current = oldNode->prev;
free(oldNode);
Deleting an element from a double
linked list

a c

head
current

oldNode=current;
oldNode->prev->next = oldNode->next;
oldNode->next->prev = oldNode->prev;
current = oldNode->prev;
free(oldNode);
Doubly Linked List Application

 Line-based text editors like Unix ed


HEADER NULL

string int main( ) {

int a = 3, b = 5;

cout << a + b << endl;

NULL
Double-Ended Queues

Recall that a queue has a front and a rear. Elements can be


added at the rear and can be removed at the front.

Front Rear

Now we also want to add elements at the front and remove


them at the rear.
Definition: A double-ended queue is a queue that supports
insertion and deletion at both the front and the rear of the
queue.

deque: pronounciated as “deck”


Double-Ended Queue (Deque)
 Richer than stack or queue.  Auxiliary queue
Supports insertions and operations:
deletions at both the front  first(): returns the element
and the end.
at the front without
 Main deque operations: removing it
 insertFirst(object o): inserts
 last(): returns the element
element o at the beginning
of the deque at the front without
 insertLast(object o): inserts
removing it
 size(): returns the number
element o at the end of the
deque of elements stored
 RemoveFirst(): removes  isEmpty(): returns a
and returns the element at Boolean value indicating
the front of the queue whether no elements are
 RemoveLast(): removes stored
and returns the element at
the end of the queue
Next Programming
Assignment
Given an array and an integer k, find the maximum for each and every
contiguous subarray of size k.
Examples:
Input :
arr[] = {1, 2, 3, 1, 4, 5, 2, 3, 6}
k=3
Output :
3345
556

Input :
arr[] =
{8, 5,
10, 7,
9, 4,
15, 12,

You might also like