βΉοΈ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://visualgo.net/en/list |
| Last Crawled | 2026-04-06 12:19:16 (22 hours ago) |
| First Indexed | 2017-04-16 06:53:56 (8 years ago) |
| HTTP Status Code | 200 |
| Meta Title | Linked List (Single, Doubly), Stack, Queue, Deque - VisuAlgo |
| Meta Description | Linked List is a data structure consisting of a group of vertices (nodes) which together represent a sequence. Under the simplest form, each vertex is composed of a data and a reference (link) to the next vertex in the sequence. Try clicking Search(77) for a sample animation on searching a value in a (Singly) Linked List.Linked List (and its variations) can be used as the underlying data structure to implement List, Stack, Queue, and Deque ADTs (read this Wikipedia article about ADT if you are not familiar with that term). Another potential data structure that can be used to implement List ADT is (resize-able) array.In this visualization, we discuss (Singly) Linked List (LL) β with a single next pointer β and its two variants: Stack and Queue, and also Doubly Linked List (DLL) β with both next and previous pointers β and its variant: Deque. |
| Meta Canonical | null |
| Boilerpipe Text | Linked List is a data structure consisting of a group of vertices (nodes) which together represent a sequence. Under the simplest form, each vertex is composed of a data and a reference (link) to the next vertex in the sequence. Try clicking
Search(77)
for a sample animation on searching a value in a (Singly) Linked List.
Linked List (and its variations) can be used as the underlying data structure to implement List, Stack, Queue, and Deque ADTs (read this
Wikipedia article about ADT
if you are not familiar with that term). Another potential data structure that can be used to implement List ADT is (resize-able)
array
.
In this visualization, we discuss (Singly) Linked List (LL) β with a single next pointer β and its two variants: Stack and Queue, and also Doubly Linked List (DLL) β with both next and previous pointers β and its variant: Deque.
Remarks
: By default, we show e-Lecture Mode for first time (or non logged-in) visitor.
If you are an NUS student and a repeat visitor, please
login
.
β
π
We decide to group five related modes involving Linked List (LL, Stack, Queue, DLL, Deque) in one single visualization page. To facilitate more diversity, we randomize the selected mode upon loading this direct URL: https://visualgo.net/en/list.
However, you can use the following URL shortcuts to access individual mode directly (only works for logged-in users who have cleared reading all 3 sectors of these lecture notes):
https://visualgo.net/en/ll
,
https://visualgo.net/en/stack
,
https://visualgo.net/en/queue
,
https://visualgo.net/en/dll
,
https://visualgo.net/en/deque
.
Pro-tip 1: Since you are not
logged-in
, you may be a first time visitor (or not an NUS student) who are not aware of the following keyboard shortcuts to navigate this e-Lecture mode:
[PageDown]
/
[PageUp]
to go to the next/previous slide, respectively, (and if the drop-down box is highlighted, you can also use
[β or β/β or β]
to do the same),and
[Esc]
to toggle between this e-Lecture mode and exploration mode.
β
β
π
Linked List data structure is commonly taught in Computer Science (CS) undergraduate courses for a few reasons:
It is a simple linear data structure,
It has a range of potential applications as a list ADT e.g., student list, event list, appointment list, etc (albeit there are other more advanced data structures that can do the same (and more) applications better) or as stack/queue/deque ADTs,
It has interesting corner/special cases to illustrate the need for a good implementation of a data structure,
It has various customization options and thus usually this Linked List data structure is taught using Object-Oriented Programming (OOP) way.
Pro-tip 2: We designed this visualization and this e-Lecture mode to look good on 1366x768 resolution
or larger
(typical modern laptop resolution in 2021). We recommend using Google Chrome to access VisuAlgo. Go to full screen mode (
F11
) to enjoy this setup. However, you can use zoom-in (
Ctrl +
) or zoom-out (
Ctrl -
) to calibrate this.
β
β
π
List is a sequence of items/data where positional order matter {a
0
, a
1
, ..., a
N-2
, a
N-1
}.
Common List ADT operations are:
get(i)
β maybe a trivial operation, return
a
i
(0-based indexing),
search(v)
β decide if item/data
v
exists (and report its position/index)
or not exist (and usually report a non existing index -1) in the list,
insert(i, v)
β insert item/data
v
specifically at position/index
i
in the list, potentially shifting the items from previous positions: [
i
..
N
-1] by one position to their right to make a space,
remove(i)
β remove item that is specifically at position/index
i
in the list, potentially shifting the items from previous positions: [
i+1
..
N
-1] by one position to their left to close the gap.
Discussion 1: What if we want to remove item with specific value
v
in the list?
Discussion 2: Can a List ADT contains duplicate items, i.e., a
i
= a
j
where i β j?
Pro-tip 3: Other than using the typical media UI at the bottom of the page, you can also control the animation playback using keyboard shortcuts (in Exploration Mode):
Spacebar
to play/pause/replay the animation,
β
/
β
to step the animation backwards/forwards, respectively, and
-
/
+
to decrease/increase the animation speed, respectively.
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
Please review
(Compact) Array
data structure that can also be used to implement List ADT.
For fixed-size collections with known max limit of number of items that will ever be needed, i.e., the max size of
M
, then array is already a reasonably good data structure for List ADT implementation.
For variable-size collections with unknown size
M
and where dynamic operations such as insert/remove are common, a simple (fixed-size) array is actually a poor choice of data structure.
For such applications, there are better data structures, including Linked List. Read on...
β
β
π
We now introduce the Linked List data structure. It uses pointers/references to allow items/data to be
non-contiguous
in memory (that is the main difference with a
simple array
). The items are ordered from index 0 to index
N
-1 by associating item
i
with its neighbour item
i+1
through a pointer.
β
β
π
In its basic form, a single vertex (node) in the Linked List has this rough structure:
struct Vertex { // we can use either C struct or C++/Python/Java class
int item; // the data is stored here, an integer in this example
Vertex* next; // this pointer tells us where is the next vertex
};
Using the default example Linked List [22 (head)->2->77->6->43->76->89 (tail)] for illustration, we have:
a
0
with its
item
= 22 and its
next
=
a
1
,
a
1
with its
item
= 2 and its
next
=
a
2
,
...
a
6
with its
item
= 89 and its
next
=
null
.
Discussion: Which one is better for a C++ implementation of Linked List? struct or class? How about Python or Java implementation?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
We also have a few additional data that we remember in this Linked List data structure. We use the default example Linked List [22 (head)->2->77->6->43->76->89 (tail)] for illustration.
The
head
pointer points to
a
0
β it is 22, nothing points to the head item,
The current number of elements
N
in the Linked List β
N = 7
elements.
The
tail
pointer points to
a
N-1
β it is
a
6
= 89, nothing is after the tail item.
That's it, we only add three more extra variables in data structure.
β
β
π
Note that there are various subtle differences found in many Computer Science textbooks on how to implement a (Singly) Linked List e.g., use tail pointer or not, circular or not, use dummy head item or not, allow duplicate items or not β see
this slide
.
Our version in this visualization (with tail pointer, not circular, without dummy head, disallow duplicate) may not be 100% the same compared to what you learn in your class but the basic ideas should remain the same.
In this visualization, each vertex has Integer item, but this can easily be changed to any other data type as needed.
β
β
π
Since we only keep the head and tail pointers, list traversal subroutine is needed to reach positions other than the head (index 0) and the tail (index
N
-1).
As this sub-routine is so frequently used, we will abstract it out as a function. The code below is written in C++.
Vertex* Get(int i) { // returns the vertex
Vertex* ptr = head; // we have to start from head
for (int k = 0; k < i; ++k) // advance forward i time(s)
ptr = ptr->next; // the pointers are pointing to the higher index
return ptr;
}
It runs in O(
N
) as
i
can be as big as index
N
-2.
Compare this with
array
where we can access index
i
in O(
1
) time.
β
β
π
As we only have direct reference to the first head item and the last tail item, plus the pointers are pointing to the
right
(higher position/index), we can only access the rest by starting from the head item and hopping through the next pointers. On the default [22 (head)->2->77->6->43->76->89 (tail)], we have:
Search(77)
β found in the example above at position/index 2 (0-based indexing).
Search(7)
β not found in the example above, and this is only known after all
N
items are examined, so
Search(v)
has O(
N
) worst case time complexity.
β
β
π
There are more cases than
array
version due to the nature of Linked List.
Most CS students who learn Linked List for the first time usually are not aware of all cases until they figure it out themselves when their Linked List code fail.
In this e-Lecture, we directly elaborate all cases.
For
insert(i, v)
, there are four (legal) possibilities, i.e., item
v
is added to:
The head (before the current first item) of the linked list,
i = 0
,
An empty linked list (which fortunately similar to the previous case),
The position beyond the last (the current tail) item of the linked list,
i = N
,
The other positions of the linked list,
i = [1..N-1]
.
β
β
π
The (C++) code for insertion at head is simple and efficient, in O(
1
):
Vertex* vtx = new Vertex(); // create new vertex vtx from item v
vtx->item = v;
vtx->next = head; // link this new vertex to the (old) head vertex
head = vtx; // the new vertex becomes the new head
Try
InsertHead(50)
, which is
insert(0, 50)
, on the example Linked ListΒ [22 (head)->2->77->6->43->76->89 (tail)].
Discussion: What happen if we use
array
implementation for insertion at head of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
Empty data structure is a common corner/special case that can often cause unexpected crash if not properly tested. It is legal to insert a new item into a currently empty list, i.e., at index
i = 0
. Fortunately, the same pseudo-code for insertion at head also works for an empty list so we can just use the same code as in
this slide
Β (with one minor change, we also need to set tail = head).
Try
InsertHead(50)
, which is
insert(0, 50)
, but on the empty Linked List [].
β
β
π
With the Linked List traversal
Get(i)
sub-routine, we can now implement insertion in the middle of the Linked List as follows (in C++):
Vertex* pre = Get(i-1); // traverse to (i-1)-th vertex, O(N)
aft = pre->next; // aft cannot be null, think about it
Vertex* vtx = new Vertex(); // create new vertex
vtx->item = v;
vtx->next = aft; // link this
pre->next = vtx; // and this
Try
Insert(3, 44)
on the example Linked ListΒ Β [22 (head)->2->77->6->43->76->89 (tail)].
Also try
Insert(6, 55)
on the same example Linked List. This is a corner case: Insert at the position of tail item, shifting the tail to one position to its right.
This operation is slow, O(
N
), due to the need for traversing the list (e.g. if
i
close to
N
-1).
β
β
π
If we also remember the tail pointer as with the implementation
in this e-Lecture
(which is advisable as it is just one additional pointer variable), we can perform insertion beyond the tail item (at
i = N
) efficiently, in O(
1
):
Vertex* vtx = new Vertex(); // this is also a C++ code
vtx->item = v; // create new vertex vtx from item v
tail->next = vtx; // just link this, as tail is the i = (N-1)-th item
tail = vtx; // now update the tail pointer
Try
InsertTail(10)
, which is
insert(7, 10)
, on the example Linked ListΒ [22 (head)->2->77->6->43->76->89 (tail)]Β . A common misconception is to say that this is insertion at tail. Insertion at tail element is
insert(N-1, v)
. Insertion
beyond
the tail is
insert(N, v)
.
Discussion: What happen if we use
array
implementation for insertion beyond the tail of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
For
remove(i)
, there are three (legal) possibilities, i.e., index
i
is:
The head (the current first item) of the linked list,
i = 0
, it affects the head pointer
The tail of the linked list,
i = N-1
, it affects the tail pointer
The other positions of the linked list,
i = [1..N-2]
.
Discussion: Compare this slide with
Insertion Cases slide
to realize the subtle differences. Is removing anything from an already empty Linked List considered 'legal'?
β
β
π
This case is straightforward (written in C++):
if (head == NULL) return; // avoid crashing when SLL is empty
Vertex* tmp = head; // so we can delete it later
head = head->next; // book keeping, update the head pointer
delete tmp; // which is the old head
Try
RemoveHead()
repeatedly on the (shorter) example Linked ListΒ [22 (head)->2->77->6 (tail)]. It will continuously working correctly up until the Linked List contains one item where the head = the tail item. We prevent execution if the LL is already empty as it is an illegal case.
Discussion: What happen if we use
array
implementation for removal of head of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
With the Linked List traversal
Get(i)
sub-routine (
discussed earlier
), we can now implement removal of the middle item of the Linked List as follows (in C++):
Vertex* pre = Get(i-1); // traverse to (i-1)-th vertex, O(N)
Vertex* del = pre->next, aft = del->next;
pre->next = aft; // bypass del
delete del;
Try
Remove(5)
, the element at index
N-2
(as
N = 7
in the exampleΒ [22 (head)->2->77->6->43->76->89 (tail)]Β .
This is the worst O(
N
) case on the example above.
Note that
Remove(N-1)
is removal at tail that requires us to update the tail pointer, see the next case.
β
β
π
We can implement the removal of the tail of the Linked List as follows, assuming that the Linked List has more than 1 item (in C++):
Vertex* pre = head;
tmp = head->next;
while (tmp->next != null) // while my neighbor is not the tail
pre = pre->next, tmp = tmp->next;
pre->next = null;
delete tmp; // tmp = (old) tail
tail = pre; // update tail pointer
Try
RemoveTail()
repeatedly on the (shorter) example Linked ListΒ [22 (head)->2->77->6 (tail)]. It will continuously working correctly up until the Linked List contains one item where the head = the tail item and we switch to
removal at head
case. We prevent execution if the LL is already empty as it is an illegal case.
β
β
π
Actually, if we also maintain the size of the Linked List
N
(compare with
this slide
), we can use the Linked List traversal sub-routine
Get(i)
to implement the removal of the tail of the Linked List this way (in C++):
Vertex* pre = Get(N-2); // go to one index just before tail, O(N)
pre->next = null;
delete tail;
tail = pre; // we have access to old tail
Notice that this operation is slow, O(
N
), just because of the need to update the tail pointer from item
N
-1 backwards by one unit to item
N
-2 so that future insertion after tail remains correct... This deficiency will be
later addressed
in Doubly Linked List variant.
Discussion: What happen if we use
array
implementation for removal of tail of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
get(i)
is slow: O(
N
).
In Linked List, we need to perform sequential access from head element.
search(v)
In the best case,
v
is found at the first position, O(
1
).
In the worst case,
v
is not found in the list and we require O(
N
) scan to determine that.
insert(i, v)
In the best case, insert at
i = 0
or at
i = N
, head and tail pointers help, O(
1
).
In the worst case, insert at
i = N-1
, we need to find the item
N
-2 just before the tail, O(
N
).
remove(i)
In the best case, remove at
i = 0
, head pointer helps, O(
1
).
In the worst case, remove at
i = N-1
, due to the need to update the tail pointer, O(
N
).
β
β
π
Pure (Singly) Linked List applications are surprisingly rare as the simpler resizeable compact array (vector) can do the job better, compare the
Linked List version
with the
compact array version
.
However, the basic concept of Linked List that allows the vertices to be non-contiguous in memory makes it an excellent resize-able data structure for the next two other Abstract Data Types:
Stack
and
Queue
.
β
β
π
Stack is a particular kind of Abstract Data Type in which the main operations on the collection are the addition of an item to the collection, known as push, only to the top of the stack and removal of an item, known as pop, only from the top of the stack.
It is known as Last-In-First-Out (LIFO) data structure, e.g., the stack of book below.
β
β
π
In most implementations and also in this visualization, Stack is basically a
protected
(Singly) Linked List where we can only peek at the head item, push a new item only to the head (
insert at head
), e.g., try
InsertHead(6)
, and pop existing item only from the head (
remove from head
), e.g., try
RemoveHead()
. All operations are O(1).
In this visualization, we orientate the (Single) Linked List top down, with the head/tail item at the top/bottom, respectively. In the example, we have [2 (top/head)->7->5->3->1->9 (bottom/tail)]. Due to vertical screen size limit (in landscape mode), we only allow a Stack of at most 7 items in this visualization.
Discussion: Can we use vector, a resizeable array, to implement Stack ADT efficiently?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
Stack has a few popular textbook applications. Some examples:
Bracket Matching,
Postfix Calculator,
A few other interesting applications that are not shown for pedagogical purposes.
β
β
π
Mathematical expression can get quite convoluted, e.g.,
{[x+2]^(2+5)-2}*(y+5)
.
Bracket Matching problem is a problem of checking whether all brackets in the given input are matched correctly, i.e., ( with ), [ with ] and { with }, and so on.
Bracket Matching is equally useful for checking the legality of a source code.
Discussion: It turns out that we can use Stack's LIFO behavior to solve this problem.
The question is how?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
Postfix expression is a mathematical expression in:
operand1 operand2 operator
format which is different from what human is most comfortable at, the Infix expression:
operand1 operator operand2
.
For example, expression
2 3 + 4 *
is the Postfix version of
(2+3)*4
.
In Postfix expression, we do not need brackets.
Discussion: It turns out that we can also use Stack to solve this problem efficiently.
The question is how?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
Queue is another Abstract Data Type in which the items in the collection are kept
in order
and the main operations on the collection are the addition of items to the back position (enqueue) and removal of items from the front position (dequeue).
It is known as
First-In-First-Out (FIFO)
data structure as the first item to be enqueued will eventually be the first item to be dequeued, as in real life queues (see below).
β
β
π
If we simply use the
compact array
implementation for this Queue ADT with
a
0
is the front of the queue and
a
N-1
is the back of the queue, we will encounter major performance issue with the
dequeue
operation.
This is because insertion at the back of a compact array is fast, O(
1
), but removal at the front of a compact array is slow due to the need to shift items, please review
this slide
.
β
β
π
Another possible array implementation is to avoid that shifting of items during dequeue operation by having
two
indices:
front
(the index of the queue front-most item, increased after a dequeue operation) and
back
(the index of the queue back-most item, also increased after an enqueue operation).
Suppose we use an array of size
M = 8
items and the content of our queue is as follows:
[
(
2
,4,1,
7
)
,-,-,-,-]
with
front = 0
(underlined)
and
back = 3
(italic)
. The current active queue elements are highlighted with
(green color)
.
If we call dequeue(), we have
[-,
(
4
,1,
7
)
,-,-,-,-]
,
front = 0+1 = 1
, and
back = 3
.
If we call enqueue(5), we have
[-,
(
4
,1,7,
5
)
,-,-,-]
,
front = 1
, and
back = 3+1 = 4
.
β
β
π
However, many dequeue and enqueue operations later, we may have
[-,-,-,-,-,
6
,2,
3
]
,
front = 5
, and
back = 7
. By now, we cannot enqueue anything else albeit we have many empty spaces at the front of the array.
If we allow both
front
and
back
indices to "wrap back" to index 0 when they have reached index
M
-1, we effectively make the array "circular" and we can use the empty spaces.
For example, if we call enqueue(8) next, we have
[
8
)
,-,-,-,-,
(
6
,2,3
]
,
front = 5
, and
back = (7+1)%8 = 0
.
β
β
π
Yet, this does not solve the main problem of fixed-size array implementation. A few more enqueue operations later, we may have
[
8,10,11,12,
13
),(
6
,2,3
]
,
front = 5
, and
back = 4
. At this point (
front = (back+1) % M)
), we cannot enqueue anything else.
Do note that if we know that our queue size will never exceed the fixed array size
M
, then the circular array idea is actually already a good way to implement Queue ADT.
However, if we do not know the upper bound of queue size, we can enlarge (double) the size of the array, e.g., make
M = 2*8 = 16
(two-times larger), but that will entail re-copying the items from index
front
to
back
in a
slow
(but rare) O(
N
) process to have
[
(
6
,2,3,8,10,11,12,
13
)
,-,-,-,-,-,-,-,-,]
,
front = 0
, and
back = 7
.
PS1: If you understand amortized analysis, this heavy O(
N
) cost when the circular array is full can actually be spread out so that each enqueue remains O(
1
) in amortized sense.
PS2: There is an alternative way to implement an efficient Queue using two Stacks. How?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
If we do not really know the the upper bound of queue size, then Singly Linked List (SLL) can be a good data structure to implement Queue ADT.
Recall that in a Queue, we only need the two extreme ends of the List, one for insertion (enqueue) only and one for removal (dequeue) only.
If we review
this slide
, we see that insertion
after tail
and removal
from head
in a Singly Linked List are fast, i.e., O(
1
). Thus, we designate the head/tail of the Singly Linked List as the front/back of the queue, respectively. Then, as the items in a Linked List are
not
stored contiguously in computer memory, our Linked List can grow and shrink as needed.
In our visualization, Queue is basically a
protected
Singly Linked List where we can only peek at the head item, enqueue a new item to one position after the current tail, e.g., try
Enqueue(random-integer)
, and dequeue existing item from the head, e.g., try
RemoveHead()
(which is essentially a dequeue operation). All operations are O(
1
).
β
β
π
Queue ADT is usually used to simulate real queues.
One super important application of Queue ADT is inside the
Breadth-First Search
graph traversal algorithm.
β
β
π
Doubly Linked List (DLL) is 99% the same as its Singly Linked List version. The main difference is that now each vertex contains
two
pointers. The
next
pointer is the same as in Singly Linked List version in which it links item
a
i
with the next item
a
i+1
, if exists. The additional
prev
pointer also links item
a
i
with the previous item
a
i-1
, if exists.
The usage of
prev
pointers makes it possible to move/iterate
backwards
at the expense of two-times memory usage requirement as now each vertex records one additional pointer. The positive side effect of this ability to move backwards is now we can address the weak
removal at tail case
of the Singly Linked List.
In this visualization, notice that the edges in Doubly Linked List (and later Deque) are undirected (bidirectional) edges.
β
β
π
The main problem of removal of the tail element in the Singly Linked List, even if we have direct access to the tail item via the tail pointer, is that we then have to update the tail pointer to point to one item just before the tail after such removal.
With Doubly Linked List ability to move
backwards
, we can find this item before the tail via
tail->prev
... Thus, we can implement removal of tail this way (in C++):
Vertex* tmp = tail; // remember tail item
tail = tail->prev; // the key step to achieve O(1) performance :O
tail->next = null; // remove this dangling reference
delete tmp; // remove the old tail
Now this operation is O(
1
). Try
RemoveTail()
on example DLL [22 (head)<->2<->77<->6<->43<->76<->89 (tail)].
β
β
π
As we have one more pointer
prev
for each vertex, their values need to be updated too during each insertion or removal. Try all these operations on example DLL [22 (head)<->2<->77<->6<->43<->76<->89 (tail)].
Try
InsertHead(50)
β additional step: 22's
prev
pointer points to new head 50.
Try
InsertTail(10)
β additional step: 10's
prev
pointer points to old tail 89.
Try
Insert(3, 44)
β additional step: 6's/44's
prev
pointers point to 44/77, respectively.
Try
RemoveHead()
β set new head 2's
prev
pointer to null.
Try
Remove(5)
β set 89's
prev
pointer to 43.
β
β
π
Double-ended queue (often abbreviated to deque, pronounced deck) is an Abstract Data Type that generalizes a Queue, for which elements can be added to or removed only from
either
the front (head) or back (tail).
In our visualization, Deque is basically a protected Doubly Linked List where we can only:
search the head/tail item (peek front/back),
insert a new item to the head/tail (try
InsertHead(50)
or
InsertTail(10)
), and
remove an existing item from the head/tail (try
RemoveHead()
or
RemoveTail()
).
All operations are O(
1
).
β
β
π
Deque are used a few advanced applications, like finding the shortest paths 0/1-weighted graph using modified BFS, on some sliding window techniques, etc.
β
β
π
Create operation is the same for all five modes.
However there are minor differences for the search/insert/remove operations among the five modes.
For Stack, you can only peek/restricted-search, push/restricted-insert, and pop/restricted-remove from the top/head.
For Queue, you can only peek/restricted-search from the front (or sometimes, the back), push/restricted-insert from the back, and pop/restricted-remove from the front.
For Deque, you can peek/restricted-search, enqueue/restricted-insert, dequeue/restricted-remove from both front/back, but not from the middle.
Single (Singly) and Doubly Linked List do not have such restrictions.
β
β
π
We have reached the end of this e-Lecture.
But read ahead for a few extra challenges.
β
β
π
The following are the more advanced insights about Linked List:
What happen if we don't store the tail pointer too?
What if we use dummy head?
What if the last tail item points back to the head item?
What need to be changed to allow duplicate items (a more general List ADT)?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various
flipped classrooms
in NUS.
If you are really a CS lecturer (or an IT teacher)
(outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (
show your University staff profile/relevant proof to Steven
) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will
NOT
be given to anyone else who is not a CS lecturer.
β
β
π
C++ STL:
forward_list
(a Singly Linked List)
stack
queue
list
(a Doubly Linked List)
deque
(actually not using Doubly Linked List but another technique, see cppreference)
Java API:
LinkedList
(already a Doubly Linked List)
Stack
Queue
(actually an interface, usually implemented using LinkedList class)
Deque
(actually an interface, usually implemented using LinkedList class)
β
β
π
For a few more interesting questions about this data structure, please practice on
Linked List
training module.
β
β
π
We also have a few programming problems that somewhat requires the usage of this Linked List, Stack, Queue, or Deque data structure:
UVa 11988 - Broken Keyboard (a.k.a. Beiju Text)
,
Kattis - backspace
, and
Kattis - integerlists
.
Try them to consolidate and improve your understanding about this data structure. You are allowed to use C++ STL, Python standard library, or Java API if that simplifies your implementation.
You have reached the last slide. Return to 'Exploration Mode' to start exploring!
Note that if you notice any bug in this visualization or if you want to request for a new visualization feature, do not hesitate to drop an email to the project leader: Dr Steven Halim via his email address: stevenhalim at gmail dot com.
β
π
Create(A)
Search
Insert
Remove
> |
| Markdown | [7](https://www.comp.nus.edu.sg/~stevenha) [VisuAlgo.net](https://visualgo.net/) /
/list
[LL]() [Stack]() [Queue]() [DLL]() [Deque]()
Exploration Mode βΏ
[e-Lecture Mode]("e-Lecture")
[Login](https://visualgo.net/login)
- [Profile](https://visualgo.net/profile)
- [Training](https://visualgo.net/training)
- [Tests](https://visualgo.net/tests)
- [Log Out](https://visualgo.net/logout)
\-7     \+7


1x
     
β
β
Linked List is a data structure consisting of a group of vertices (nodes) which together represent a sequence. Under the simplest form, each vertex is composed of a data and a reference (link) to the next vertex in the sequence. Try clicking Search(77) for a sample animation on searching a value in a (Singly) Linked List.
Linked List (and its variations) can be used as the underlying data structure to implement List, Stack, Queue, and Deque ADTs (read this [Wikipedia article about ADT](https://en.wikipedia.org/wiki/Abstract_data_type) if you are not familiar with that term). Another potential data structure that can be used to implement List ADT is (resize-able) [array](https://visualgo.net/en/array).
In this visualization, we discuss (Singly) Linked List (LL) β with a single next pointer β and its two variants: Stack and Queue, and also Doubly Linked List (DLL) β with both next and previous pointers β and its variant: Deque.
***
**Remarks**: By default, we show e-Lecture Mode for first time (or non logged-in) visitor.
If you are an NUS student and a repeat visitor, please [login](https://visualgo.net/login).
β
π
We decide to group five related modes involving Linked List (LL, Stack, Queue, DLL, Deque) in one single visualization page. To facilitate more diversity, we randomize the selected mode upon loading this direct URL: https://visualgo.net/en/list.
However, you can use the following URL shortcuts to access individual mode directly (only works for logged-in users who have cleared reading all 3 sectors of these lecture notes):
1. [https://visualgo.net/en/ll](https://visualgo.net/en/ll)
,
2. [https://visualgo.net/en/stack](https://visualgo.net/en/stack)
,
3. [https://visualgo.net/en/queue](https://visualgo.net/en/queue)
,
4. [https://visualgo.net/en/dll](https://visualgo.net/en/dll)
,
5. [https://visualgo.net/en/deque](https://visualgo.net/en/deque)
.
***
Pro-tip 1: Since you are not [logged-in](https://visualgo.net/login), you may be a first time visitor (or not an NUS student) who are not aware of the following keyboard shortcuts to navigate this e-Lecture mode: **\[PageDown\]**/**\[PageUp\]** to go to the next/previous slide, respectively, (and if the drop-down box is highlighted, you can also use **\[β or β/β or β\]** to do the same),and **\[Esc\]** to toggle between this e-Lecture mode and exploration mode.
β
β
π
Linked List data structure is commonly taught in Computer Science (CS) undergraduate courses for a few reasons:
1. It is a simple linear data structure,
2. It has a range of potential applications as a list ADT e.g., student list, event list, appointment list, etc (albeit there are other more advanced data structures that can do the same (and more) applications better) or as stack/queue/deque ADTs,
3. It has interesting corner/special cases to illustrate the need for a good implementation of a data structure,
4. It has various customization options and thus usually this Linked List data structure is taught using Object-Oriented Programming (OOP) way.
***
Pro-tip 2: We designed this visualization and this e-Lecture mode to look good on 1366x768 resolution **or larger** (typical modern laptop resolution in 2021). We recommend using Google Chrome to access VisuAlgo. Go to full screen mode (**F11**) to enjoy this setup. However, you can use zoom-in (**Ctrl +**) or zoom-out (**Ctrl -**) to calibrate this.
β
β
π
List is a sequence of items/data where positional order matter {a0, a1, ..., aN-2, aN-1}.
Common List ADT operations are:
1. get(i)
β maybe a trivial operation, return
ai
(0-based indexing),
2. search(v)
β decide if item/data **v** exists (and report its position/index)
or not exist (and usually report a non existing index -1) in the list,
3. insert(i, v)
β insert item/data **v** specifically at position/index **i** in the list, potentially shifting the items from previous positions: \[**i**..**N**\-1\] by one position to their right to make a space,
4. remove(i)
β remove item that is specifically at position/index **i** in the list, potentially shifting the items from previous positions: \[**i+1**..**N**\-1\] by one position to their left to close the gap.
Discussion 1: What if we want to remove item with specific value **v** in the list?
Discussion 2: Can a List ADT contains duplicate items, i.e., ai = aj where i β j?
***
Pro-tip 3: Other than using the typical media UI at the bottom of the page, you can also control the animation playback using keyboard shortcuts (in Exploration Mode): **Spacebar** to play/pause/replay the animation, **β**/**β** to step the animation backwards/forwards, respectively, and **\-**/**\+** to decrease/increase the animation speed, respectively.
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Please review [(Compact) Array](https://visualgo.net/array) data structure that can also be used to implement List ADT.
For fixed-size collections with known max limit of number of items that will ever be needed, i.e., the max size of **M**, then array is already a reasonably good data structure for List ADT implementation.
For variable-size collections with unknown size **M** and where dynamic operations such as insert/remove are common, a simple (fixed-size) array is actually a poor choice of data structure.
For such applications, there are better data structures, including Linked List. Read on...
β
β
π
We now introduce the Linked List data structure. It uses pointers/references to allow items/data to be **non-contiguous** in memory (that is the main difference with a [simple array](https://visualgo.net/en/list?slide=2-2)). The items are ordered from index 0 to index **N**\-1 by associating item **i** with its neighbour item **i+1** through a pointer.

β
β
π
In its basic form, a single vertex (node) in the Linked List has this rough structure:
```
struct Vertex { // we can use either C struct or C++/Python/Java class
int item; // the data is stored here, an integer in this example
Vertex* next; // this pointer tells us where is the next vertex
};
```
Using the default example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] for illustration, we have:
**a0** with its **item** = 22 and its **next** = **a1**,
**a1** with its **item** = 2 and its **next** = **a2**,
...
**a6** with its **item** = 89 and its **next** = **null**.
Discussion: Which one is better for a C++ implementation of Linked List? struct or class? How about Python or Java implementation?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
We also have a few additional data that we remember in this Linked List data structure. We use the default example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] for illustration.
1. The **head** pointer points to **a0** β it is 22, nothing points to the head item,
2. The current number of elements **N** in the Linked List β **N = 7** elements.
3. The **tail** pointer points to **aN-1** β it is **a6** = 89, nothing is after the tail item.
That's it, we only add three more extra variables in data structure.
β
β
π
Note that there are various subtle differences found in many Computer Science textbooks on how to implement a (Singly) Linked List e.g., use tail pointer or not, circular or not, use dummy head item or not, allow duplicate items or not β see [this slide](https://visualgo.net/en/list?slide=9-1).
Our version in this visualization (with tail pointer, not circular, without dummy head, disallow duplicate) may not be 100% the same compared to what you learn in your class but the basic ideas should remain the same.
In this visualization, each vertex has Integer item, but this can easily be changed to any other data type as needed.
β
β
π
Since we only keep the head and tail pointers, list traversal subroutine is needed to reach positions other than the head (index 0) and the tail (index **N**\-1).
As this sub-routine is so frequently used, we will abstract it out as a function. The code below is written in C++.
```
Vertex* Get(int i) { // returns the vertex
Vertex* ptr = head; // we have to start from head
for (int k = 0; k < i; ++k) // advance forward i time(s)
ptr = ptr->next; // the pointers are pointing to the higher index
return ptr;
}
```
It runs in O(**N**) as **i** can be as big as index **N**\-2.
Compare this with [array](https://visualgo.net/en/list?slide=2-4) where we can access index **i** in O(**1**) time.
β
β
π
As we only have direct reference to the first head item and the last tail item, plus the pointers are pointing to the **right** (higher position/index), we can only access the rest by starting from the head item and hopping through the next pointers. On the default \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\], we have:
Search(77) β found in the example above at position/index 2 (0-based indexing).
Search(7) β not found in the example above, and this is only known after all **N** items are examined, so Search(v) has O(**N**) worst case time complexity.
β
β
π
There are more cases than [array](https://visualgo.net/en/list?slide=2-4) version due to the nature of Linked List.
Most CS students who learn Linked List for the first time usually are not aware of all cases until they figure it out themselves when their Linked List code fail.
In this e-Lecture, we directly elaborate all cases.
For insert(i, v), there are four (legal) possibilities, i.e., item **v** is added to:
1. The head (before the current first item) of the linked list, **i = 0**,
2. An empty linked list (which fortunately similar to the previous case),
3. The position beyond the last (the current tail) item of the linked list, **i = N**,
4. The other positions of the linked list, **i = \[1..N-1\]**.
β
β
π
The (C++) code for insertion at head is simple and efficient, in O(**1**):
```
Vertex* vtx = new Vertex(); // create new vertex vtx from item v
vtx->item = v;
vtx->next = head; // link this new vertex to the (old) head vertex
head = vtx; // the new vertex becomes the new head
```
Try InsertHead(50), which is insert(0, 50), on the example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\].
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for insertion at head of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Empty data structure is a common corner/special case that can often cause unexpected crash if not properly tested. It is legal to insert a new item into a currently empty list, i.e., at index **i = 0**. Fortunately, the same pseudo-code for insertion at head also works for an empty list so we can just use the same code as in [this slide](https://visualgo.net/en/list?slide=3-8) (with one minor change, we also need to set tail = head).
Try InsertHead(50), which is insert(0, 50), but on the empty Linked List \[\].
β
β
π
With the Linked List traversal Get(i) sub-routine, we can now implement insertion in the middle of the Linked List as follows (in C++):
```
Vertex* pre = Get(i-1); // traverse to (i-1)-th vertex, O(N)
aft = pre->next; // aft cannot be null, think about it
Vertex* vtx = new Vertex(); // create new vertex
vtx->item = v;
vtx->next = aft; // link this
pre->next = vtx; // and this
```
Try Insert(3, 44) on the example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\].
Also try Insert(6, 55) on the same example Linked List. This is a corner case: Insert at the position of tail item, shifting the tail to one position to its right.
This operation is slow, O(**N**), due to the need for traversing the list (e.g. if **i** close to **N**\-1).
β
β
π
If we also remember the tail pointer as with the implementation [in this e-Lecture](https://visualgo.net/en/list?slide=3-3) (which is advisable as it is just one additional pointer variable), we can perform insertion beyond the tail item (at **i = N**) efficiently, in O(**1**):
```
Vertex* vtx = new Vertex(); // this is also a C++ code
vtx->item = v; // create new vertex vtx from item v
tail->next = vtx; // just link this, as tail is the i = (N-1)-th item
tail = vtx; // now update the tail pointer
```
Try InsertTail(10), which is insert(7, 10), on the example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] . A common misconception is to say that this is insertion at tail. Insertion at tail element is insert(N-1, v). Insertion **beyond** the tail is insert(N, v).
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for insertion beyond the tail of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
For remove(i), there are three (legal) possibilities, i.e., index **i** is:
1. The head (the current first item) of the linked list, **i = 0**, it affects the head pointer
2. The tail of the linked list, **i = N-1**, it affects the tail pointer
3. The other positions of the linked list, **i = \[1..N-2\]**.
Discussion: Compare this slide with [Insertion Cases slide](https://visualgo.net/en/list?slide=3-7) to realize the subtle differences. Is removing anything from an already empty Linked List considered 'legal'?
β
β
π
This case is straightforward (written in C++):
```
if (head == NULL) return; // avoid crashing when SLL is empty
Vertex* tmp = head; // so we can delete it later
head = head->next; // book keeping, update the head pointer
delete tmp; // which is the old head
```
Try RemoveHead() repeatedly on the (shorter) example Linked List \[22 (head)-\>2-\>77-\>6 (tail)\]. It will continuously working correctly up until the Linked List contains one item where the head = the tail item. We prevent execution if the LL is already empty as it is an illegal case.
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for removal of head of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
With the Linked List traversal Get(i) sub-routine ([discussed earlier](https://visualgo.net/en/list?slide=3-5)), we can now implement removal of the middle item of the Linked List as follows (in C++):
```
Vertex* pre = Get(i-1); // traverse to (i-1)-th vertex, O(N)
Vertex* del = pre->next, aft = del->next;
pre->next = aft; // bypass del
delete del;
```
Try Remove(5), the element at index **N-2** (as **N = 7** in the example \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] .
This is the worst O(**N**) case on the example above.
Note that **Remove(N-1)** is removal at tail that requires us to update the tail pointer, see the next case.
β
β
π
We can implement the removal of the tail of the Linked List as follows, assuming that the Linked List has more than 1 item (in C++):
```
Vertex* pre = head;
tmp = head->next;
while (tmp->next != null) // while my neighbor is not the tail
pre = pre->next, tmp = tmp->next;
pre->next = null;
delete tmp; // tmp = (old) tail
tail = pre; // update tail pointer
```
Try RemoveTail() repeatedly on the (shorter) example Linked List \[22 (head)-\>2-\>77-\>6 (tail)\]. It will continuously working correctly up until the Linked List contains one item where the head = the tail item and we switch to [removal at head](https://visualgo.net/en/list?slide=3-15) case. We prevent execution if the LL is already empty as it is an illegal case.
β
β
π
Actually, if we also maintain the size of the Linked List **N** (compare with [this slide](https://visualgo.net/en/list?slide=3-3)), we can use the Linked List traversal sub-routine Get(i) to implement the removal of the tail of the Linked List this way (in C++):
```
Vertex* pre = Get(N-2); // go to one index just before tail, O(N)
pre->next = null;
delete tail;
tail = pre; // we have access to old tail
```
Notice that this operation is slow, O(**N**), just because of the need to update the tail pointer from item **N**\-1 backwards by one unit to item **N**\-2 so that future insertion after tail remains correct... This deficiency will be [later addressed](https://visualgo.net/en/list?slide=6-1) in Doubly Linked List variant.
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for removal of tail of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
get(i) is slow: O(**N**).
In Linked List, we need to perform sequential access from head element.
search(v)
In the best case, **v** is found at the first position, O(**1**).
In the worst case, **v** is not found in the list and we require O(**N**) scan to determine that.
insert(i, v)
In the best case, insert at **i = 0** or at **i = N**, head and tail pointers help, O(**1**).
In the worst case, insert at **i = N-1**, we need to find the item **N**\-2 just before the tail, O(**N**).
remove(i)
In the best case, remove at **i = 0**, head pointer helps, O(**1**).
In the worst case, remove at **i = N-1**, due to the need to update the tail pointer, O(**N**).
β
β
π
Pure (Singly) Linked List applications are surprisingly rare as the simpler resizeable compact array (vector) can do the job better, compare the [Linked List version](https://visualgo.net/en/list?slide=3-21) with the [compact array version](https://visualgo.net/en/list?slide=2-5).
However, the basic concept of Linked List that allows the vertices to be non-contiguous in memory makes it an excellent resize-able data structure for the next two other Abstract Data Types: [Stack](https://visualgo.net/en/list?slide=4) and [Queue](https://visualgo.net/en/list?slide=5).
β
β
π
Stack is a particular kind of Abstract Data Type in which the main operations on the collection are the addition of an item to the collection, known as push, only to the top of the stack and removal of an item, known as pop, only from the top of the stack.
It is known as Last-In-First-Out (LIFO) data structure, e.g., the stack of book below.

β
β
π
In most implementations and also in this visualization, Stack is basically a **protected** (Singly) Linked List where we can only peek at the head item, push a new item only to the head ([insert at head](https://visualgo.net/en/list?slide=3-9)), e.g., try InsertHead(6), and pop existing item only from the head ([remove from head](https://visualgo.net/en/list?slide=3-14)), e.g., try RemoveHead(). All operations are O(1).
In this visualization, we orientate the (Single) Linked List top down, with the head/tail item at the top/bottom, respectively. In the example, we have \[2 (top/head)-\>7-\>5-\>3-\>1-\>9 (bottom/tail)\]. Due to vertical screen size limit (in landscape mode), we only allow a Stack of at most 7 items in this visualization.
Discussion: Can we use vector, a resizeable array, to implement Stack ADT efficiently?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Stack has a few popular textbook applications. Some examples:
1. Bracket Matching,
2. Postfix Calculator,
3. A few other interesting applications that are not shown for pedagogical purposes.
β
β
π
Mathematical expression can get quite convoluted, e.g., {\[x+2\]^(2+5)-2}\*(y+5).
Bracket Matching problem is a problem of checking whether all brackets in the given input are matched correctly, i.e., ( with ), \[ with \] and { with }, and so on.
Bracket Matching is equally useful for checking the legality of a source code.
Discussion: It turns out that we can use Stack's LIFO behavior to solve this problem.
The question is how?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Postfix expression is a mathematical expression in: operand1 operand2 operator format which is different from what human is most comfortable at, the Infix expression: operand1 operator operand2.
For example, expression 2 3 + 4 \* is the Postfix version of (2+3)\*4.
In Postfix expression, we do not need brackets.
Discussion: It turns out that we can also use Stack to solve this problem efficiently.
The question is how?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Queue is another Abstract Data Type in which the items in the collection are kept **in order** and the main operations on the collection are the addition of items to the back position (enqueue) and removal of items from the front position (dequeue).
It is known as **First-In-First-Out (FIFO)** data structure as the first item to be enqueued will eventually be the first item to be dequeued, as in real life queues (see below).

β
β
π
If we simply use the [compact array](https://visualgo.net/en/list?slide=2-3) implementation for this Queue ADT with a0 is the front of the queue and aN-1 is the back of the queue, we will encounter major performance issue with the **dequeue** operation.
This is because insertion at the back of a compact array is fast, O(**1**), but removal at the front of a compact array is slow due to the need to shift items, please review [this slide](https://visualgo.net/en/list?slide=2-5).
β
β
π
Another possible array implementation is to avoid that shifting of items during dequeue operation by having **two** indices: **front** (the index of the queue front-most item, increased after a dequeue operation) and **back** (the index of the queue back-most item, also increased after an enqueue operation).
Suppose we use an array of size **M = 8** items and the content of our queue is as follows: \[ ( 2 ,4,1,*7*) ,-,-,-,-\] with **front = 0** (underlined) and ***back = 3** (italic)*. The current active queue elements are highlighted with (green color).
If we call dequeue(), we have \[-, ( 4 ,1,*7*) ,-,-,-,-\], **front = 0+1 = 1**, and ***back = 3***.
If we call enqueue(5), we have \[-, ( 4 ,1,7,*5*) ,-,-,-\], **front = 1**, and ***back = 3+1 = 4***.
β
β
π
However, many dequeue and enqueue operations later, we may have \[-,-,-,-,-, 6 ,2,*3* \], **front = 5**, and ***back = 7***. By now, we cannot enqueue anything else albeit we have many empty spaces at the front of the array.
If we allow both **front** and **back** indices to "wrap back" to index 0 when they have reached index **M**\-1, we effectively make the array "circular" and we can use the empty spaces.
For example, if we call enqueue(8) next, we have \[*8*),-,-,-,-, ( 6 ,2,3 \], **front = 5**, and ***back = (7+1)%8 = 0***.
β
β
π
Yet, this does not solve the main problem of fixed-size array implementation. A few more enqueue operations later, we may have \[ 8,10,11,12,*13*),( 6 ,2,3 \], **front = 5**, and ***back = 4***. At this point (**front = (back+1) % M)**), we cannot enqueue anything else.
Do note that if we know that our queue size will never exceed the fixed array size **M**, then the circular array idea is actually already a good way to implement Queue ADT.
However, if we do not know the upper bound of queue size, we can enlarge (double) the size of the array, e.g., make **M = 2\*8 = 16** (two-times larger), but that will entail re-copying the items from index **front** to ***back*** in a **slow** (but rare) O(**N**) process to have \[ ( 6 ,2,3,8,10,11,12,*13*) ,-,-,-,-,-,-,-,-,\], **front = 0**, and ***back = 7***.
PS1: If you understand amortized analysis, this heavy O(**N**) cost when the circular array is full can actually be spread out so that each enqueue remains O(**1**) in amortized sense.
PS2: There is an alternative way to implement an efficient Queue using two Stacks. How?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
If we do not really know the the upper bound of queue size, then Singly Linked List (SLL) can be a good data structure to implement Queue ADT.
Recall that in a Queue, we only need the two extreme ends of the List, one for insertion (enqueue) only and one for removal (dequeue) only.
If we review [this slide](https://visualgo.net/en/list?slide=3-21), we see that insertion **after tail** and removal **from head** in a Singly Linked List are fast, i.e., O(**1**). Thus, we designate the head/tail of the Singly Linked List as the front/back of the queue, respectively. Then, as the items in a Linked List are **not** stored contiguously in computer memory, our Linked List can grow and shrink as needed.
In our visualization, Queue is basically a **protected** Singly Linked List where we can only peek at the head item, enqueue a new item to one position after the current tail, e.g., try Enqueue(random-integer), and dequeue existing item from the head, e.g., try RemoveHead() (which is essentially a dequeue operation). All operations are O(**1**).
β
β
π
Queue ADT is usually used to simulate real queues.
One super important application of Queue ADT is inside the [Breadth-First Search](https://visualgo.net/en/sssp) graph traversal algorithm.
β
β
π
Doubly Linked List (DLL) is 99% the same as its Singly Linked List version. The main difference is that now each vertex contains **two** pointers. The **next** pointer is the same as in Singly Linked List version in which it links item **ai** with the next item **ai+1**, if exists. The additional **prev** pointer also links item **ai** with the previous item **ai-1**, if exists.
The usage of **prev** pointers makes it possible to move/iterate **backwards** at the expense of two-times memory usage requirement as now each vertex records one additional pointer. The positive side effect of this ability to move backwards is now we can address the weak [removal at tail case](https://visualgo.net/en/list?slide=3-18) of the Singly Linked List.
In this visualization, notice that the edges in Doubly Linked List (and later Deque) are undirected (bidirectional) edges.
β
β
π
The main problem of removal of the tail element in the Singly Linked List, even if we have direct access to the tail item via the tail pointer, is that we then have to update the tail pointer to point to one item just before the tail after such removal.
With Doubly Linked List ability to move **backwards**, we can find this item before the tail via tail-\>prev... Thus, we can implement removal of tail this way (in C++):
```
Vertex* tmp = tail; // remember tail item
tail = tail->prev; // the key step to achieve O(1) performance :O
tail->next = null; // remove this dangling reference
delete tmp; // remove the old tail
```
Now this operation is O(**1**). Try RemoveTail() on example DLL \[22 (head)\<-\>2\<-\>77\<-\>6\<-\>43\<-\>76\<-\>89 (tail)\].
β
β
π
As we have one more pointer **prev** for each vertex, their values need to be updated too during each insertion or removal. Try all these operations on example DLL \[22 (head)\<-\>2\<-\>77\<-\>6\<-\>43\<-\>76\<-\>89 (tail)\].
Try InsertHead(50) β additional step: 22's **prev** pointer points to new head 50.
Try InsertTail(10) β additional step: 10's **prev** pointer points to old tail 89.
Try Insert(3, 44) β additional step: 6's/44's **prev** pointers point to 44/77, respectively.
Try RemoveHead() β set new head 2's **prev** pointer to null.
Try Remove(5) β set 89's **prev** pointer to 43.
β
β
π
Double-ended queue (often abbreviated to deque, pronounced deck) is an Abstract Data Type that generalizes a Queue, for which elements can be added to or removed only from **either** the front (head) or back (tail).
In our visualization, Deque is basically a protected Doubly Linked List where we can only:
search the head/tail item (peek front/back),
insert a new item to the head/tail (try InsertHead(50) or InsertTail(10)), and
remove an existing item from the head/tail (try RemoveHead() or RemoveTail()).
All operations are O(**1**).
β
β
π
Deque are used a few advanced applications, like finding the shortest paths 0/1-weighted graph using modified BFS, on some sliding window techniques, etc.
β
β
π
Create operation is the same for all five modes.
However there are minor differences for the search/insert/remove operations among the five modes.
For Stack, you can only peek/restricted-search, push/restricted-insert, and pop/restricted-remove from the top/head.
For Queue, you can only peek/restricted-search from the front (or sometimes, the back), push/restricted-insert from the back, and pop/restricted-remove from the front.
For Deque, you can peek/restricted-search, enqueue/restricted-insert, dequeue/restricted-remove from both front/back, but not from the middle.
Single (Singly) and Doubly Linked List do not have such restrictions.
β
β
π
We have reached the end of this e-Lecture.
But read ahead for a few extra challenges.
β
β
π
The following are the more advanced insights about Linked List:
1. What happen if we don't store the tail pointer too?
2. What if we use dummy head?
3. What if the last tail item points back to the head item?
4. What need to be changed to allow duplicate items (a more general List ADT)?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
C++ STL:
[forward\_list](http://en.cppreference.com/w/cpp/container/forward_list) (a Singly Linked List)
[stack](http://en.cppreference.com/w/cpp/container/stack)
[queue](http://en.cppreference.com/w/cpp/container/queue)
[list](http://en.cppreference.com/w/cpp/container/list) (a Doubly Linked List)
[deque](http://en.cppreference.com/w/cpp/container/deque) (actually not using Doubly Linked List but another technique, see cppreference)
Java API:
[LinkedList](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html) (already a Doubly Linked List)
[Stack](https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html)
[Queue](https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html) (actually an interface, usually implemented using LinkedList class)
[Deque](https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html) (actually an interface, usually implemented using LinkedList class)
β
β
π
Python:
[list](https://docs.python.org/3/tutorial/datastructures.html) for List/Stack/Queue
[deque](https://docs.python.org/3/library/collections.html#collections.deque)
OCaml:
[List](https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html)
[Stack](https://caml.inria.fr/pub/docs/manual-ocaml/libref/Stack.html)
[Queue](https://caml.inria.fr/pub/docs/manual-ocaml/libref/Queue.html)
No built-in support for Deque
β
β
π
For a few more interesting questions about this data structure, please practice on [Linked List](https://visualgo.net/training?diff=Medium&n=7&tl=0&module=list) training module.
β
β
π
We also have a few programming problems that somewhat requires the usage of this Linked List, Stack, Queue, or Deque data structure:
[UVa 11988 - Broken Keyboard (a.k.a. Beiju Text)](https://uva.onlinejudge.org/external/119/11988.pdf),
[Kattis - backspace](https://open.kattis.com/problems/backspace), and
[Kattis - integerlists](https://open.kattis.com/problems/integerlists).
Try them to consolidate and improve your understanding about this data structure. You are allowed to use C++ STL, Python standard library, or Java API if that simplifies your implementation.
***
You have reached the last slide. Return to 'Exploration Mode' to start exploring\!
Note that if you notice any bug in this visualization or if you want to request for a new visualization feature, do not hesitate to drop an email to the project leader: Dr Steven Halim via his email address: stevenhalim at gmail dot com.
β
π
X
Close
Please rotate your device to landscape mode for a better user experience
Please make the window wider for a better user experience
Create(A)
Search
Insert
Remove
\>
Empty
User Defined List
A =
Go
N =
Random
Random Sorted
Front
Back
v =
Go
v =
Go
v =
Go
v =
Front
Back
i = 0 (Head), specify v =
v =
Go
i = N (After Tail), specify v =
v =
Go
specify both i in \[1..N-1\] and v =
i =
v =
Go
K =
Front
Back
1x (Dequeue)
K =
Kx (Dequeue)
Remove i = 0 (Head)
Remove i = N-1 (Tail)
specify i in \[1..N-2\]
i =
Go
1x (Pop)
K =
Kx (Pop)
[1\.0x]() [Share]() [About]() [Team]() [Terms of use]() [Privacy Policy]() [Open in Browser](https://visualgo.net/en/list)
#### About
β
Initially conceived in 2011 by Associate Professor Steven Halim, VisuAlgo aimed to facilitate a deeper understanding of data structures and algorithms for his students by providing a self-paced, interactive learning platform.
Featuring numerous advanced algorithms discussed in Dr. Steven Halim's book, 'Competitive Programming' β co-authored with Dr. Felix Halim and Dr. Suhendry Effendy β VisuAlgo remains the exclusive platform for visualizing and animating several of these complex algorithms even after a decade.
While primarily designed for National University of Singapore (NUS) students enrolled in various data structure and algorithm courses (e.g., CS1010/equivalent, CS2040/equivalent (including IT5003), CS3230, CS3233, and CS4234), VisuAlgo also serves as a valuable resource for inquisitive minds worldwide, promoting online learning.
Initially, VisuAlgo was not designed for small touch screens like smartphones, as intricate algorithm visualizations required substantial pixel space and click-and-drag interactions. For an optimal user experience, a minimum screen resolution of 1366x768 is recommended. However, since April 2022, a mobile (lite) version of VisuAlgo has been made available, making it possible to use a subset of VisuAlgo features on smartphone screens.
VisuAlgo remains a work in progress, with the ongoing development of more complex visualizations. At present, the platform features 24 visualization modules.
Equipped with a built-in question generator and answer verifier, VisuAlgo's "online quiz system" enables students to test their knowledge of basic data structures and algorithms. Questions are randomly generated based on specific rules, and students' answers are automatically graded upon submission to our grading server. As more CS instructors adopt this online quiz system worldwide, it could effectively eliminate manual basic data structure and algorithm questions from standard Computer Science exams in many universities. By assigning a small (but non-zero) weight to passing the online quiz, CS instructors can significantly enhance their students' mastery of these basic concepts, as they have access to an almost unlimited number of practice questions that can be instantly verified before taking the online quiz. Each VisuAlgo visualization module now includes its own online quiz component.
VisuAlgo has been translated into three primary languages: English, Chinese, and Indonesian. Additionally, we have authored public notes about VisuAlgo in various languages, including Indonesian, Korean, Vietnamese, and Thai:
[id](https://www.facebook.com/notes/steven-halim/httpidvisualgonet-visualisasi-struktur-data-dan-algoritma-dengan-animasi/10153236934439689)
,
[kr](http://blog.naver.com/visualgo_nus)
,
[vn](https://www.facebook.com/groups/163215593699283/permalink/824003417620494/)
,
[th](http://pantip.com/topic/32736343)
.
#### Team
β
**Project Leader & Advisor (Jul 2011-present)**
[Associate Professor Steven Halim](https://www.comp.nus.edu.sg/~stevenha/), School of Computing (SoC), National University of Singapore (NUS)
[Dr Felix Halim](https://www.linkedin.com/in/felixhalim/), Senior Software Engineer, Google (Mountain View)
**Undergraduate Student Researchers 1**
**CDTL TEG 1: Jul 2011-Apr 2012**: Koh Zi Chun, Victor Loh Bo Huai
**Final Year Project/UROP students 1**
**Jul 2012-Dec 2013**: Phan Thi Quynh Trang, Peter Phandi, Albert Millardo Tjindradinata, Nguyen Hoang Duy
**Jun 2013-Apr 2014** [Rose Marie Tan Zhao Yun](https://www.rosemarietan.com/), Ivan Reinaldo
**Undergraduate Student Researchers 2**
**CDTL TEG 2: May 2014-Jul 2014**: Jonathan Irvin Gunawan, Nathan Azaria, Ian Leow Tze Wei, Nguyen Viet Dung, Nguyen Khac Tung, Steven Kester Yuwono, Cao Shengze, Mohan Jishnu
**Final Year Project/UROP students 2**
**Jun 2014-Apr 2015**: Erin Teo Yi Ling, Wang Zi
**Jun 2016-Dec 2017**: Truong Ngoc Khanh, John Kevin Tjahjadi, Gabriella Michelle, Muhammad Rais Fathin Mudzakir
**Aug 2021-Apr 2023**: Liu Guangyuan, Manas Vegi, Sha Long, Vuong Hoang Long, Ting Xiao, Lim Dewen Aloysius
**Undergraduate Student Researchers 3**
**Optiver: Aug 2023-Oct 2023**: Bui Hong Duc, Tay Ngan Lin
**Final Year Project/UROP students 3**
**Aug 2023-Apr 2024**: Xiong Jingya, Radian Krisno, Ng Wee Han, Tan Chee Heng
**Aug 2024-Apr 2025**: Edbert Geraldy Cangdinata, Huang Xing Chen, Nicholas Patrick
List of translators who have contributed β₯ 100 translations can be found at [statistics](https://visualgo.net/statistics) page.
**Acknowledgements**
NUS [CDTL](https://nus.edu.sg/cdtl) gave Teaching Enhancement Grant to kickstart this project.
For Academic Year 2023/24 - present (currently AY 2025/26) - generous donations from Optiver will be used to further develop VisuAlgo.
#### Terms of use
β
VisuAlgo is generously offered at no cost to the global Computer Science community. If you appreciate VisuAlgo, we kindly request that you **spread the word about its existence to fellow Computer Science students and instructors**. You can share VisuAlgo through social media platforms (e.g., Facebook, YouTube, Instagram, TikTok, Twitter, etc), course webpages, blog reviews, emails, and more.
Data Structures and Algorithms (DSA) students and instructors are welcome to use this website directly for their classes. If you capture screenshots or videos from this site, feel free to use them elsewhere, provided that you cite the URL of this website (<https://visualgo.net>) and/or the list of publications below as references. However, please refrain from downloading VisuAlgo's client-side files and hosting them on your website, as this constitutes plagiarism. At this time, we do not permit others to fork this project or create VisuAlgo variants. Personal use of an offline copy of the client-side VisuAlgo is acceptable.
Please note that VisuAlgo's online quiz component has a substantial server-side element, and it is not easy to save server-side scripts and databases locally. Currently, the general public can access the online quiz system only through the 'training mode.' The 'test mode' offers a more controlled environment for using randomly generated questions and automatic verification in real examinations at NUS.
**List of Publications**
This work has been presented at the CLI Workshop at the ICPC World Finals 2012 (Poland, Warsaw) and at the IOI Conference at IOI 2012 (Sirmione-Montichiari, Italy). You can click [this link](https://ioinformatics.org/journal/INFOL099.pdf) to read our 2012 paper about this system (it was not yet called VisuAlgo back in 2012) and [this link](https://ioinformatics.org/journal/v9_2015_243_245.pdf) for the short update in 2015 (to link VisuAlgo name with the previous project).
**Bug Reports or Request for New Features**
VisuAlgo is not a finished project. Associate Professor Steven Halim is still actively improving VisuAlgo. If you are using VisuAlgo and spot a bug in any of our visualization page/online quiz tool or if you want to request for new features, please contact Associate Professor Steven Halim. His contact is the concatenation of his name and add gmail dot com.
#### Privacy Policy
β
**Version 1.2 (Updated Fri, 18 Aug 2023).**
Since Fri, 18 Aug 2023, we no longer use Google Analytics. Thus, all cookies that we use now are solely for the operations of this website. The annoying cookie-consent popup is now turned off even for first-time visitors.
Since Fri, 07 Jun 2023, thanks to a generous donation by Optiver, anyone in the world can self-create a VisuAlgo account to store a few customization settings (e.g., layout mode, default language, playback speed, etc).
Additionally, for NUS students, by using a VisuAlgo account (a tuple of NUS official email address, student name as in the class roster, and a password that is encrypted on the server side β no other personal data is stored), you are giving a consent for your course lecturer to keep track of your e-lecture slides reading and online quiz training progresses that is needed to run the course smoothly. Your VisuAlgo account will also be needed for taking NUS official VisuAlgo Online Quizzes and thus passing your account credentials to another person to do the Online Quiz on your behalf constitutes an academic offense. Your user account will be purged after the conclusion of the course unless you choose to keep your account (OPT-IN). Access to the full VisuAlgo database (with encrypted passwords) is limited to Prof Halim himself.
For other CS lecturers worldwide who have written to Steven, a VisuAlgo account (your (non-NUS) email address, you can use any display name, and encrypted password) is needed to distinguish your online credential versus the rest of the world. Your account will have CS lecturer specific features, namely the ability to see the hidden slides that contain (interesting) answers to the questions presented in the preceding slides before the hidden slides. You can also access Hard setting of the VisuAlgo Online Quizzes. You can freely use the material to enhance your data structures and algorithm classes. Note that there can be other CS lecturer specific features in the future.
For anyone with VisuAlgo account, you can remove your own account by yourself should you wish to no longer be associated with VisuAlgo tool. |
| Readable Markdown | 

Linked List is a data structure consisting of a group of vertices (nodes) which together represent a sequence. Under the simplest form, each vertex is composed of a data and a reference (link) to the next vertex in the sequence. Try clicking Search(77) for a sample animation on searching a value in a (Singly) Linked List.
Linked List (and its variations) can be used as the underlying data structure to implement List, Stack, Queue, and Deque ADTs (read this [Wikipedia article about ADT](https://en.wikipedia.org/wiki/Abstract_data_type) if you are not familiar with that term). Another potential data structure that can be used to implement List ADT is (resize-able) [array](https://visualgo.net/en/array).
In this visualization, we discuss (Singly) Linked List (LL) β with a single next pointer β and its two variants: Stack and Queue, and also Doubly Linked List (DLL) β with both next and previous pointers β and its variant: Deque.
***
**Remarks**: By default, we show e-Lecture Mode for first time (or non logged-in) visitor.
If you are an NUS student and a repeat visitor, please [login](https://visualgo.net/login).
β
π
We decide to group five related modes involving Linked List (LL, Stack, Queue, DLL, Deque) in one single visualization page. To facilitate more diversity, we randomize the selected mode upon loading this direct URL: https://visualgo.net/en/list.
However, you can use the following URL shortcuts to access individual mode directly (only works for logged-in users who have cleared reading all 3 sectors of these lecture notes):
1. [https://visualgo.net/en/ll](https://visualgo.net/en/ll)
,
2. [https://visualgo.net/en/stack](https://visualgo.net/en/stack)
,
3. [https://visualgo.net/en/queue](https://visualgo.net/en/queue)
,
4. [https://visualgo.net/en/dll](https://visualgo.net/en/dll)
,
5. [https://visualgo.net/en/deque](https://visualgo.net/en/deque)
.
***
Pro-tip 1: Since you are not [logged-in](https://visualgo.net/login), you may be a first time visitor (or not an NUS student) who are not aware of the following keyboard shortcuts to navigate this e-Lecture mode: **\[PageDown\]**/**\[PageUp\]** to go to the next/previous slide, respectively, (and if the drop-down box is highlighted, you can also use **\[β or β/β or β\]** to do the same),and **\[Esc\]** to toggle between this e-Lecture mode and exploration mode.
β
β
π
Linked List data structure is commonly taught in Computer Science (CS) undergraduate courses for a few reasons:
1. It is a simple linear data structure,
2. It has a range of potential applications as a list ADT e.g., student list, event list, appointment list, etc (albeit there are other more advanced data structures that can do the same (and more) applications better) or as stack/queue/deque ADTs,
3. It has interesting corner/special cases to illustrate the need for a good implementation of a data structure,
4. It has various customization options and thus usually this Linked List data structure is taught using Object-Oriented Programming (OOP) way.
***
Pro-tip 2: We designed this visualization and this e-Lecture mode to look good on 1366x768 resolution **or larger** (typical modern laptop resolution in 2021). We recommend using Google Chrome to access VisuAlgo. Go to full screen mode (**F11**) to enjoy this setup. However, you can use zoom-in (**Ctrl +**) or zoom-out (**Ctrl -**) to calibrate this.
β
β
π
List is a sequence of items/data where positional order matter {a0, a1, ..., aN-2, aN-1}.
Common List ADT operations are:
1. get(i)
β maybe a trivial operation, return
ai
(0-based indexing),
2. search(v)
β decide if item/data **v** exists (and report its position/index)
or not exist (and usually report a non existing index -1) in the list,
3. insert(i, v)
β insert item/data **v** specifically at position/index **i** in the list, potentially shifting the items from previous positions: \[**i**..**N**\-1\] by one position to their right to make a space,
4. remove(i)
β remove item that is specifically at position/index **i** in the list, potentially shifting the items from previous positions: \[**i+1**..**N**\-1\] by one position to their left to close the gap.
Discussion 1: What if we want to remove item with specific value **v** in the list?
Discussion 2: Can a List ADT contains duplicate items, i.e., ai = aj where i β j?
***
Pro-tip 3: Other than using the typical media UI at the bottom of the page, you can also control the animation playback using keyboard shortcuts (in Exploration Mode): **Spacebar** to play/pause/replay the animation, **β**/**β** to step the animation backwards/forwards, respectively, and **\-**/**\+** to decrease/increase the animation speed, respectively.
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Please review [(Compact) Array](https://visualgo.net/array) data structure that can also be used to implement List ADT.
For fixed-size collections with known max limit of number of items that will ever be needed, i.e., the max size of **M**, then array is already a reasonably good data structure for List ADT implementation.
For variable-size collections with unknown size **M** and where dynamic operations such as insert/remove are common, a simple (fixed-size) array is actually a poor choice of data structure.
For such applications, there are better data structures, including Linked List. Read on...
β
β
π
We now introduce the Linked List data structure. It uses pointers/references to allow items/data to be **non-contiguous** in memory (that is the main difference with a [simple array](https://visualgo.net/en/list?slide=2-2)). The items are ordered from index 0 to index **N**\-1 by associating item **i** with its neighbour item **i+1** through a pointer.

β
β
π
In its basic form, a single vertex (node) in the Linked List has this rough structure:
```
struct Vertex { // we can use either C struct or C++/Python/Java class
int item; // the data is stored here, an integer in this example
Vertex* next; // this pointer tells us where is the next vertex
};
```
Using the default example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] for illustration, we have:
**a0** with its **item** = 22 and its **next** = **a1**,
**a1** with its **item** = 2 and its **next** = **a2**,
...
**a6** with its **item** = 89 and its **next** = **null**.
Discussion: Which one is better for a C++ implementation of Linked List? struct or class? How about Python or Java implementation?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
We also have a few additional data that we remember in this Linked List data structure. We use the default example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] for illustration.
1. The **head** pointer points to **a0** β it is 22, nothing points to the head item,
2. The current number of elements **N** in the Linked List β **N = 7** elements.
3. The **tail** pointer points to **aN-1** β it is **a6** = 89, nothing is after the tail item.
That's it, we only add three more extra variables in data structure.
β
β
π
Note that there are various subtle differences found in many Computer Science textbooks on how to implement a (Singly) Linked List e.g., use tail pointer or not, circular or not, use dummy head item or not, allow duplicate items or not β see [this slide](https://visualgo.net/en/list?slide=9-1).
Our version in this visualization (with tail pointer, not circular, without dummy head, disallow duplicate) may not be 100% the same compared to what you learn in your class but the basic ideas should remain the same.
In this visualization, each vertex has Integer item, but this can easily be changed to any other data type as needed.
β
β
π
Since we only keep the head and tail pointers, list traversal subroutine is needed to reach positions other than the head (index 0) and the tail (index **N**\-1).
As this sub-routine is so frequently used, we will abstract it out as a function. The code below is written in C++.
```
Vertex* Get(int i) { // returns the vertex
Vertex* ptr = head; // we have to start from head
for (int k = 0; k < i; ++k) // advance forward i time(s)
ptr = ptr->next; // the pointers are pointing to the higher index
return ptr;
}
```
It runs in O(**N**) as **i** can be as big as index **N**\-2.
Compare this with [array](https://visualgo.net/en/list?slide=2-4) where we can access index **i** in O(**1**) time.
β
β
π
As we only have direct reference to the first head item and the last tail item, plus the pointers are pointing to the **right** (higher position/index), we can only access the rest by starting from the head item and hopping through the next pointers. On the default \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\], we have:
Search(77) β found in the example above at position/index 2 (0-based indexing).
Search(7) β not found in the example above, and this is only known after all **N** items are examined, so Search(v) has O(**N**) worst case time complexity.
β
β
π
There are more cases than [array](https://visualgo.net/en/list?slide=2-4) version due to the nature of Linked List.
Most CS students who learn Linked List for the first time usually are not aware of all cases until they figure it out themselves when their Linked List code fail.
In this e-Lecture, we directly elaborate all cases.
For insert(i, v), there are four (legal) possibilities, i.e., item **v** is added to:
1. The head (before the current first item) of the linked list, **i = 0**,
2. An empty linked list (which fortunately similar to the previous case),
3. The position beyond the last (the current tail) item of the linked list, **i = N**,
4. The other positions of the linked list, **i = \[1..N-1\]**.
β
β
π
The (C++) code for insertion at head is simple and efficient, in O(**1**):
```
Vertex* vtx = new Vertex(); // create new vertex vtx from item v
vtx->item = v;
vtx->next = head; // link this new vertex to the (old) head vertex
head = vtx; // the new vertex becomes the new head
```
Try InsertHead(50), which is insert(0, 50), on the example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\].
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for insertion at head of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Empty data structure is a common corner/special case that can often cause unexpected crash if not properly tested. It is legal to insert a new item into a currently empty list, i.e., at index **i = 0**. Fortunately, the same pseudo-code for insertion at head also works for an empty list so we can just use the same code as in [this slide](https://visualgo.net/en/list?slide=3-8) (with one minor change, we also need to set tail = head).
Try InsertHead(50), which is insert(0, 50), but on the empty Linked List \[\].
β
β
π
With the Linked List traversal Get(i) sub-routine, we can now implement insertion in the middle of the Linked List as follows (in C++):
```
Vertex* pre = Get(i-1); // traverse to (i-1)-th vertex, O(N)
aft = pre->next; // aft cannot be null, think about it
Vertex* vtx = new Vertex(); // create new vertex
vtx->item = v;
vtx->next = aft; // link this
pre->next = vtx; // and this
```
Try Insert(3, 44) on the example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\].
Also try Insert(6, 55) on the same example Linked List. This is a corner case: Insert at the position of tail item, shifting the tail to one position to its right.
This operation is slow, O(**N**), due to the need for traversing the list (e.g. if **i** close to **N**\-1).
β
β
π
If we also remember the tail pointer as with the implementation [in this e-Lecture](https://visualgo.net/en/list?slide=3-3) (which is advisable as it is just one additional pointer variable), we can perform insertion beyond the tail item (at **i = N**) efficiently, in O(**1**):
```
Vertex* vtx = new Vertex(); // this is also a C++ code
vtx->item = v; // create new vertex vtx from item v
tail->next = vtx; // just link this, as tail is the i = (N-1)-th item
tail = vtx; // now update the tail pointer
```
Try InsertTail(10), which is insert(7, 10), on the example Linked List \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] . A common misconception is to say that this is insertion at tail. Insertion at tail element is insert(N-1, v). Insertion **beyond** the tail is insert(N, v).
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for insertion beyond the tail of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
For remove(i), there are three (legal) possibilities, i.e., index **i** is:
1. The head (the current first item) of the linked list, **i = 0**, it affects the head pointer
2. The tail of the linked list, **i = N-1**, it affects the tail pointer
3. The other positions of the linked list, **i = \[1..N-2\]**.
Discussion: Compare this slide with [Insertion Cases slide](https://visualgo.net/en/list?slide=3-7) to realize the subtle differences. Is removing anything from an already empty Linked List considered 'legal'?
β
β
π
This case is straightforward (written in C++):
```
if (head == NULL) return; // avoid crashing when SLL is empty
Vertex* tmp = head; // so we can delete it later
head = head->next; // book keeping, update the head pointer
delete tmp; // which is the old head
```
Try RemoveHead() repeatedly on the (shorter) example Linked List \[22 (head)-\>2-\>77-\>6 (tail)\]. It will continuously working correctly up until the Linked List contains one item where the head = the tail item. We prevent execution if the LL is already empty as it is an illegal case.
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for removal of head of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
With the Linked List traversal Get(i) sub-routine ([discussed earlier](https://visualgo.net/en/list?slide=3-5)), we can now implement removal of the middle item of the Linked List as follows (in C++):
```
Vertex* pre = Get(i-1); // traverse to (i-1)-th vertex, O(N)
Vertex* del = pre->next, aft = del->next;
pre->next = aft; // bypass del
delete del;
```
Try Remove(5), the element at index **N-2** (as **N = 7** in the example \[22 (head)-\>2-\>77-\>6-\>43-\>76-\>89 (tail)\] .
This is the worst O(**N**) case on the example above.
Note that **Remove(N-1)** is removal at tail that requires us to update the tail pointer, see the next case.
β
β
π
We can implement the removal of the tail of the Linked List as follows, assuming that the Linked List has more than 1 item (in C++):
```
Vertex* pre = head;
tmp = head->next;
while (tmp->next != null) // while my neighbor is not the tail
pre = pre->next, tmp = tmp->next;
pre->next = null;
delete tmp; // tmp = (old) tail
tail = pre; // update tail pointer
```
Try RemoveTail() repeatedly on the (shorter) example Linked List \[22 (head)-\>2-\>77-\>6 (tail)\]. It will continuously working correctly up until the Linked List contains one item where the head = the tail item and we switch to [removal at head](https://visualgo.net/en/list?slide=3-15) case. We prevent execution if the LL is already empty as it is an illegal case.
β
β
π
Actually, if we also maintain the size of the Linked List **N** (compare with [this slide](https://visualgo.net/en/list?slide=3-3)), we can use the Linked List traversal sub-routine Get(i) to implement the removal of the tail of the Linked List this way (in C++):
```
Vertex* pre = Get(N-2); // go to one index just before tail, O(N)
pre->next = null;
delete tail;
tail = pre; // we have access to old tail
```
Notice that this operation is slow, O(**N**), just because of the need to update the tail pointer from item **N**\-1 backwards by one unit to item **N**\-2 so that future insertion after tail remains correct... This deficiency will be [later addressed](https://visualgo.net/en/list?slide=6-1) in Doubly Linked List variant.
Discussion: What happen if we use [array](https://visualgo.net/en/list?slide=2-5) implementation for removal of tail of the list?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
get(i) is slow: O(**N**).
In Linked List, we need to perform sequential access from head element.
search(v)
In the best case, **v** is found at the first position, O(**1**).
In the worst case, **v** is not found in the list and we require O(**N**) scan to determine that.
insert(i, v)
In the best case, insert at **i = 0** or at **i = N**, head and tail pointers help, O(**1**).
In the worst case, insert at **i = N-1**, we need to find the item **N**\-2 just before the tail, O(**N**).
remove(i)
In the best case, remove at **i = 0**, head pointer helps, O(**1**).
In the worst case, remove at **i = N-1**, due to the need to update the tail pointer, O(**N**).
β
β
π
Pure (Singly) Linked List applications are surprisingly rare as the simpler resizeable compact array (vector) can do the job better, compare the [Linked List version](https://visualgo.net/en/list?slide=3-21) with the [compact array version](https://visualgo.net/en/list?slide=2-5).
However, the basic concept of Linked List that allows the vertices to be non-contiguous in memory makes it an excellent resize-able data structure for the next two other Abstract Data Types: [Stack](https://visualgo.net/en/list?slide=4) and [Queue](https://visualgo.net/en/list?slide=5).
β
β
π
Stack is a particular kind of Abstract Data Type in which the main operations on the collection are the addition of an item to the collection, known as push, only to the top of the stack and removal of an item, known as pop, only from the top of the stack.
It is known as Last-In-First-Out (LIFO) data structure, e.g., the stack of book below.

β
β
π
In most implementations and also in this visualization, Stack is basically a **protected** (Singly) Linked List where we can only peek at the head item, push a new item only to the head ([insert at head](https://visualgo.net/en/list?slide=3-9)), e.g., try InsertHead(6), and pop existing item only from the head ([remove from head](https://visualgo.net/en/list?slide=3-14)), e.g., try RemoveHead(). All operations are O(1).
In this visualization, we orientate the (Single) Linked List top down, with the head/tail item at the top/bottom, respectively. In the example, we have \[2 (top/head)-\>7-\>5-\>3-\>1-\>9 (bottom/tail)\]. Due to vertical screen size limit (in landscape mode), we only allow a Stack of at most 7 items in this visualization.
Discussion: Can we use vector, a resizeable array, to implement Stack ADT efficiently?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Stack has a few popular textbook applications. Some examples:
1. Bracket Matching,
2. Postfix Calculator,
3. A few other interesting applications that are not shown for pedagogical purposes.
β
β
π
Mathematical expression can get quite convoluted, e.g., {\[x+2\]^(2+5)-2}\*(y+5).
Bracket Matching problem is a problem of checking whether all brackets in the given input are matched correctly, i.e., ( with ), \[ with \] and { with }, and so on.
Bracket Matching is equally useful for checking the legality of a source code.
Discussion: It turns out that we can use Stack's LIFO behavior to solve this problem.
The question is how?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Postfix expression is a mathematical expression in: operand1 operand2 operator format which is different from what human is most comfortable at, the Infix expression: operand1 operator operand2.
For example, expression 2 3 + 4 \* is the Postfix version of (2+3)\*4.
In Postfix expression, we do not need brackets.
Discussion: It turns out that we can also use Stack to solve this problem efficiently.
The question is how?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
Queue is another Abstract Data Type in which the items in the collection are kept **in order** and the main operations on the collection are the addition of items to the back position (enqueue) and removal of items from the front position (dequeue).
It is known as **First-In-First-Out (FIFO)** data structure as the first item to be enqueued will eventually be the first item to be dequeued, as in real life queues (see below).

β
β
π
If we simply use the [compact array](https://visualgo.net/en/list?slide=2-3) implementation for this Queue ADT with a0 is the front of the queue and aN-1 is the back of the queue, we will encounter major performance issue with the **dequeue** operation.
This is because insertion at the back of a compact array is fast, O(**1**), but removal at the front of a compact array is slow due to the need to shift items, please review [this slide](https://visualgo.net/en/list?slide=2-5).
β
β
π
Another possible array implementation is to avoid that shifting of items during dequeue operation by having **two** indices: **front** (the index of the queue front-most item, increased after a dequeue operation) and **back** (the index of the queue back-most item, also increased after an enqueue operation).
Suppose we use an array of size **M = 8** items and the content of our queue is as follows: \[ ( 2 ,4,1,*7*) ,-,-,-,-\] with **front = 0** (underlined) and ***back = 3** (italic)*. The current active queue elements are highlighted with (green color).
If we call dequeue(), we have \[-, ( 4 ,1,*7*) ,-,-,-,-\], **front = 0+1 = 1**, and ***back = 3***.
If we call enqueue(5), we have \[-, ( 4 ,1,7,*5*) ,-,-,-\], **front = 1**, and ***back = 3+1 = 4***.
β
β
π
However, many dequeue and enqueue operations later, we may have \[-,-,-,-,-, 6 ,2,*3* \], **front = 5**, and ***back = 7***. By now, we cannot enqueue anything else albeit we have many empty spaces at the front of the array.
If we allow both **front** and **back** indices to "wrap back" to index 0 when they have reached index **M**\-1, we effectively make the array "circular" and we can use the empty spaces.
For example, if we call enqueue(8) next, we have \[*8*),-,-,-,-, ( 6 ,2,3 \], **front = 5**, and ***back = (7+1)%8 = 0***.
β
β
π
Yet, this does not solve the main problem of fixed-size array implementation. A few more enqueue operations later, we may have \[ 8,10,11,12,*13*),( 6 ,2,3 \], **front = 5**, and ***back = 4***. At this point (**front = (back+1) % M)**), we cannot enqueue anything else.
Do note that if we know that our queue size will never exceed the fixed array size **M**, then the circular array idea is actually already a good way to implement Queue ADT.
However, if we do not know the upper bound of queue size, we can enlarge (double) the size of the array, e.g., make **M = 2\*8 = 16** (two-times larger), but that will entail re-copying the items from index **front** to ***back*** in a **slow** (but rare) O(**N**) process to have \[ ( 6 ,2,3,8,10,11,12,*13*) ,-,-,-,-,-,-,-,-,\], **front = 0**, and ***back = 7***.
PS1: If you understand amortized analysis, this heavy O(**N**) cost when the circular array is full can actually be spread out so that each enqueue remains O(**1**) in amortized sense.
PS2: There is an alternative way to implement an efficient Queue using two Stacks. How?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
If we do not really know the the upper bound of queue size, then Singly Linked List (SLL) can be a good data structure to implement Queue ADT.
Recall that in a Queue, we only need the two extreme ends of the List, one for insertion (enqueue) only and one for removal (dequeue) only.
If we review [this slide](https://visualgo.net/en/list?slide=3-21), we see that insertion **after tail** and removal **from head** in a Singly Linked List are fast, i.e., O(**1**). Thus, we designate the head/tail of the Singly Linked List as the front/back of the queue, respectively. Then, as the items in a Linked List are **not** stored contiguously in computer memory, our Linked List can grow and shrink as needed.
In our visualization, Queue is basically a **protected** Singly Linked List where we can only peek at the head item, enqueue a new item to one position after the current tail, e.g., try Enqueue(random-integer), and dequeue existing item from the head, e.g., try RemoveHead() (which is essentially a dequeue operation). All operations are O(**1**).
β
β
π
Queue ADT is usually used to simulate real queues.
One super important application of Queue ADT is inside the [Breadth-First Search](https://visualgo.net/en/sssp) graph traversal algorithm.
β
β
π
Doubly Linked List (DLL) is 99% the same as its Singly Linked List version. The main difference is that now each vertex contains **two** pointers. The **next** pointer is the same as in Singly Linked List version in which it links item **ai** with the next item **ai+1**, if exists. The additional **prev** pointer also links item **ai** with the previous item **ai-1**, if exists.
The usage of **prev** pointers makes it possible to move/iterate **backwards** at the expense of two-times memory usage requirement as now each vertex records one additional pointer. The positive side effect of this ability to move backwards is now we can address the weak [removal at tail case](https://visualgo.net/en/list?slide=3-18) of the Singly Linked List.
In this visualization, notice that the edges in Doubly Linked List (and later Deque) are undirected (bidirectional) edges.
β
β
π
The main problem of removal of the tail element in the Singly Linked List, even if we have direct access to the tail item via the tail pointer, is that we then have to update the tail pointer to point to one item just before the tail after such removal.
With Doubly Linked List ability to move **backwards**, we can find this item before the tail via tail-\>prev... Thus, we can implement removal of tail this way (in C++):
```
Vertex* tmp = tail; // remember tail item
tail = tail->prev; // the key step to achieve O(1) performance :O
tail->next = null; // remove this dangling reference
delete tmp; // remove the old tail
```
Now this operation is O(**1**). Try RemoveTail() on example DLL \[22 (head)\<-\>2\<-\>77\<-\>6\<-\>43\<-\>76\<-\>89 (tail)\].
β
β
π
As we have one more pointer **prev** for each vertex, their values need to be updated too during each insertion or removal. Try all these operations on example DLL \[22 (head)\<-\>2\<-\>77\<-\>6\<-\>43\<-\>76\<-\>89 (tail)\].
Try InsertHead(50) β additional step: 22's **prev** pointer points to new head 50.
Try InsertTail(10) β additional step: 10's **prev** pointer points to old tail 89.
Try Insert(3, 44) β additional step: 6's/44's **prev** pointers point to 44/77, respectively.
Try RemoveHead() β set new head 2's **prev** pointer to null.
Try Remove(5) β set 89's **prev** pointer to 43.
β
β
π
Double-ended queue (often abbreviated to deque, pronounced deck) is an Abstract Data Type that generalizes a Queue, for which elements can be added to or removed only from **either** the front (head) or back (tail).
In our visualization, Deque is basically a protected Doubly Linked List where we can only:
search the head/tail item (peek front/back),
insert a new item to the head/tail (try InsertHead(50) or InsertTail(10)), and
remove an existing item from the head/tail (try RemoveHead() or RemoveTail()).
All operations are O(**1**).
β
β
π
Deque are used a few advanced applications, like finding the shortest paths 0/1-weighted graph using modified BFS, on some sliding window techniques, etc.
β
β
π
Create operation is the same for all five modes.
However there are minor differences for the search/insert/remove operations among the five modes.
For Stack, you can only peek/restricted-search, push/restricted-insert, and pop/restricted-remove from the top/head.
For Queue, you can only peek/restricted-search from the front (or sometimes, the back), push/restricted-insert from the back, and pop/restricted-remove from the front.
For Deque, you can peek/restricted-search, enqueue/restricted-insert, dequeue/restricted-remove from both front/back, but not from the middle.
Single (Singly) and Doubly Linked List do not have such restrictions.
β
β
π
We have reached the end of this e-Lecture.
But read ahead for a few extra challenges.
β
β
π
The following are the more advanced insights about Linked List:
1. What happen if we don't store the tail pointer too?
2. What if we use dummy head?
3. What if the last tail item points back to the head item?
4. What need to be changed to allow duplicate items (a more general List ADT)?
β
β
π
The content of this interesting slide (the answer of the usually intriguing discussion point from the earlier slide) is hidden and only available for legitimate CS lecturer worldwide. This mechanism is used in the various [flipped classrooms](https://en.wikipedia.org/wiki/Flipped_classroom) in NUS.
**If you are really a CS lecturer (or an IT teacher)** (outside of NUS) and are interested to know the answers, please drop an email to stevenhalim at gmail dot com (**show your University staff profile/relevant proof to Steven**) for Steven to manually activate this CS lecturer-only feature for you.
FAQ: This feature will **NOT** be given to anyone else who is not a CS lecturer.
β
β
π
C++ STL:
[forward\_list](http://en.cppreference.com/w/cpp/container/forward_list) (a Singly Linked List)
[stack](http://en.cppreference.com/w/cpp/container/stack)
[queue](http://en.cppreference.com/w/cpp/container/queue)
[list](http://en.cppreference.com/w/cpp/container/list) (a Doubly Linked List)
[deque](http://en.cppreference.com/w/cpp/container/deque) (actually not using Doubly Linked List but another technique, see cppreference)
Java API:
[LinkedList](https://docs.oracle.com/javase/8/docs/api/java/util/LinkedList.html) (already a Doubly Linked List)
[Stack](https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html)
[Queue](https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html) (actually an interface, usually implemented using LinkedList class)
[Deque](https://docs.oracle.com/javase/8/docs/api/java/util/Deque.html) (actually an interface, usually implemented using LinkedList class)
β
β
π
For a few more interesting questions about this data structure, please practice on [Linked List](https://visualgo.net/training?diff=Medium&n=7&tl=0&module=list) training module.
β
β
π
We also have a few programming problems that somewhat requires the usage of this Linked List, Stack, Queue, or Deque data structure:
[UVa 11988 - Broken Keyboard (a.k.a. Beiju Text)](https://uva.onlinejudge.org/external/119/11988.pdf),
[Kattis - backspace](https://open.kattis.com/problems/backspace), and
[Kattis - integerlists](https://open.kattis.com/problems/integerlists).
Try them to consolidate and improve your understanding about this data structure. You are allowed to use C++ STL, Python standard library, or Java API if that simplifies your implementation.
***
You have reached the last slide. Return to 'Exploration Mode' to start exploring\!
Note that if you notice any bug in this visualization or if you want to request for a new visualization feature, do not hesitate to drop an email to the project leader: Dr Steven Halim via his email address: stevenhalim at gmail dot com.
β
π
Create(A)
Search
Insert
Remove
\> |
| Shard | 150 (laksa) |
| Root Hash | 1741799502994858350 |
| Unparsed URL | net,visualgo!/en/list s443 |