What is the time complexity of enqueue and dequeue of a queue implemented with a singly linked list?Implement...
Discrepancy in P/E ratio of stocks in Robinhood app?
Meaning of ご休憩一時間コース
Two functions in the same line
Are Giants classified as Beasts or Beings?
Can a hotel cancel a confirmed reservation?
Why is button three on trumpet almost never used alone?
Can we use the stored gravitational potential energy of a building to produce power?
Is there a kind of consulting service in Buddhism?
Do authors have to be politically correct in article-writing?
If all harmonics are generated by plucking, how does a guitar string produce a pure frequency sound?
Why do neural networks need so many training examples to perform?
Why is c4 a better move in this position?
I am on the US no-fly list. What can I do in order to be allowed on flights which go through US airspace?
SQL Create Script DDL Table from View
How to interpret this PubChem record of L-Alanine
When does coming up with an idea constitute sufficient contribution for authorship?
Can pricing be copyrighted?
How can I introduce myself to a party without saying that I am a rogue?
math reviews in "Zentralblatt für Mathematik und ihre Grenzgebiete"
How do you funnel food off a cutting board?
Am I using the wrong word all along?
Am I a Rude Number?
How to implement expandbefore, similarly to expandafter?
Called into a meeting and told we are being made redundant (laid off) and "not to share outside". Can I tell my partner?
What is the time complexity of enqueue and dequeue of a queue implemented with a singly linked list?
Implement queue with a linked list; why would it be bad to insert at the head and remove at the tail?Complexity of algorithm inserting an element in a circular linked list at the front endTime complexity for searching $k-th$ element from starting and ending of a linked listImplementing wait-free consensus with queuesWhy to implement Open list in Heuristic search with priority queueCorrect way to implement linked listWhat is the type of linked list where order doesn't matterFinding an element in a infinite unsorted doubly linked listFinding the nth to last node in a linked listLinked List in Maximal Scoring Subsequences Algorithm
$begingroup$
I’m trying to understand the time complexity of a queue implemented with a linked list data structure. My book says that we can the implement a queue in O(1) time by:
- enqueueing at the back
- dequeueing at the head
and it also says
Note that although adding an element to the tail is constant time,
removing an element from the tail is O(n) as we have to find the new
tail
I know that adding a new node to my queue at the head (enqueue) takes O(1) since I have the head pointer. Similarly, removing a node at the head (dequeue) will take O(1) as well. But I don’t understand why adding an element at the back (enqueue) takes O(1), while removing it (dequeue) takes O(n). It would make more sense to me if enqueueing at the back took O(n) rather than O(1), since in both cases (adding/removing at the back) would need to find the tail pointer and therefore it would need to traverse the entire list.
algorithms time-complexity linked-lists queues
New contributor
$endgroup$
add a comment |
$begingroup$
I’m trying to understand the time complexity of a queue implemented with a linked list data structure. My book says that we can the implement a queue in O(1) time by:
- enqueueing at the back
- dequeueing at the head
and it also says
Note that although adding an element to the tail is constant time,
removing an element from the tail is O(n) as we have to find the new
tail
I know that adding a new node to my queue at the head (enqueue) takes O(1) since I have the head pointer. Similarly, removing a node at the head (dequeue) will take O(1) as well. But I don’t understand why adding an element at the back (enqueue) takes O(1), while removing it (dequeue) takes O(n). It would make more sense to me if enqueueing at the back took O(n) rather than O(1), since in both cases (adding/removing at the back) would need to find the tail pointer and therefore it would need to traverse the entire list.
algorithms time-complexity linked-lists queues
New contributor
$endgroup$
6
$begingroup$
Please do not remove significant information from your question once you have received an answer. We want the pair of question and answer to be useful for others in the future, so try to keep things complete.
$endgroup$
– Discrete lizard♦
18 hours ago
add a comment |
$begingroup$
I’m trying to understand the time complexity of a queue implemented with a linked list data structure. My book says that we can the implement a queue in O(1) time by:
- enqueueing at the back
- dequeueing at the head
and it also says
Note that although adding an element to the tail is constant time,
removing an element from the tail is O(n) as we have to find the new
tail
I know that adding a new node to my queue at the head (enqueue) takes O(1) since I have the head pointer. Similarly, removing a node at the head (dequeue) will take O(1) as well. But I don’t understand why adding an element at the back (enqueue) takes O(1), while removing it (dequeue) takes O(n). It would make more sense to me if enqueueing at the back took O(n) rather than O(1), since in both cases (adding/removing at the back) would need to find the tail pointer and therefore it would need to traverse the entire list.
algorithms time-complexity linked-lists queues
New contributor
$endgroup$
I’m trying to understand the time complexity of a queue implemented with a linked list data structure. My book says that we can the implement a queue in O(1) time by:
- enqueueing at the back
- dequeueing at the head
and it also says
Note that although adding an element to the tail is constant time,
removing an element from the tail is O(n) as we have to find the new
tail
I know that adding a new node to my queue at the head (enqueue) takes O(1) since I have the head pointer. Similarly, removing a node at the head (dequeue) will take O(1) as well. But I don’t understand why adding an element at the back (enqueue) takes O(1), while removing it (dequeue) takes O(n). It would make more sense to me if enqueueing at the back took O(n) rather than O(1), since in both cases (adding/removing at the back) would need to find the tail pointer and therefore it would need to traverse the entire list.
algorithms time-complexity linked-lists queues
algorithms time-complexity linked-lists queues
New contributor
New contributor
edited 4 hours ago
amalloy
1035
1035
New contributor
asked yesterday
AppeAppe
312
312
New contributor
New contributor
6
$begingroup$
Please do not remove significant information from your question once you have received an answer. We want the pair of question and answer to be useful for others in the future, so try to keep things complete.
$endgroup$
– Discrete lizard♦
18 hours ago
add a comment |
6
$begingroup$
Please do not remove significant information from your question once you have received an answer. We want the pair of question and answer to be useful for others in the future, so try to keep things complete.
$endgroup$
– Discrete lizard♦
18 hours ago
6
6
$begingroup$
Please do not remove significant information from your question once you have received an answer. We want the pair of question and answer to be useful for others in the future, so try to keep things complete.
$endgroup$
– Discrete lizard♦
18 hours ago
$begingroup$
Please do not remove significant information from your question once you have received an answer. We want the pair of question and answer to be useful for others in the future, so try to keep things complete.
$endgroup$
– Discrete lizard♦
18 hours ago
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
Enqueueing
You don't need to traverse the entire list to find the new tail, you just need to add a new node where the current tail points to and set that node as the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function enqueue(value) {
node = new Node(value) // O(1)
tail.next = node // O(1)
tail = node // O(1)
size++ // O(1)
}
From which we can conclude that the time complexity is $O(1)$.
Dequeueing
For dequeueing, we only need to set the next node of the current head as the new head and return the value of the old head.
Note: Don't forget that if the new head is set to null
, the tail should be set to null
as well:
Pseudocode (assuming that head != null
and tail != null
):
function dequeue() {
value = head.value // O(1)
head = head.next // O(1)
size-- // O(1)
if (head == null) { // O(1)
tail = null // O(1)
}
return value // O(1)
}
All these operations have $O(1)$ time complexity, which makes the time complexity of the dequeue function $O(1)$ as well.
Searching
Searching for a value is done by traversing through all the items, starting from the head. In the worst case scenario, you would need to traverse the entire queue, which makes the worst-case time complexity $O(n)$.
For example, if you want to remove the tail, the time complexity would be $O(n)$. This is because you would need to find the new tail for the queue and since the tail does not have access to the previous element in a singly linked list, you would need to search the entire queue for the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function removeLast() {
// Edge case when there is only 1 element in the queue.
if (head == tail) { // O(1)
value = head.value // O(1)
head = null // O(1)
tail = null // O(1)
return value // O(1)
}
// Searching for the new tail.
newTail = head // O(1)
while (newTail.next != tail) { // O(n)
newTail = newTail.next // O(1)
}
value = tail.value // O(1)
newTail.next = null // O(1)
tail = newTail // O(1)
return tail // O(1)
}
From which can be seen that the time complexity is indeed $O(n)$.
New contributor
$endgroup$
$begingroup$
Enqueue doesn't handle an empty list. While dequeue does handle when the list becomes empty.
$endgroup$
– ratchet freak
3 hours ago
add a comment |
$begingroup$
The comment in the book apparently assumes that your linked list implementation maintains two pointers, head
that points to the first node in the list, and last
that points to the last node.
With this design, appending to the list is simply:
list.last.next = newNode;
list.last = newNode;
But removing the last node requires finding the 2nd to last node, so you can clear its next
link, and change the last
pointer to point to it. This requires scanning the list to find the node where node.next == list.last
.
You could conceivably also have a list.secondToLast
pointer, but that doesn't solve the problem, because when you remove the last node you need to change this to point to the previous third to last node, and this problem recurses to the entire list.
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
});
});
}, "mathjax-editing");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "419"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Appe is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcs.stackexchange.com%2fquestions%2f105029%2fwhat-is-the-time-complexity-of-enqueue-and-dequeue-of-a-queue-implemented-with-a%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Enqueueing
You don't need to traverse the entire list to find the new tail, you just need to add a new node where the current tail points to and set that node as the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function enqueue(value) {
node = new Node(value) // O(1)
tail.next = node // O(1)
tail = node // O(1)
size++ // O(1)
}
From which we can conclude that the time complexity is $O(1)$.
Dequeueing
For dequeueing, we only need to set the next node of the current head as the new head and return the value of the old head.
Note: Don't forget that if the new head is set to null
, the tail should be set to null
as well:
Pseudocode (assuming that head != null
and tail != null
):
function dequeue() {
value = head.value // O(1)
head = head.next // O(1)
size-- // O(1)
if (head == null) { // O(1)
tail = null // O(1)
}
return value // O(1)
}
All these operations have $O(1)$ time complexity, which makes the time complexity of the dequeue function $O(1)$ as well.
Searching
Searching for a value is done by traversing through all the items, starting from the head. In the worst case scenario, you would need to traverse the entire queue, which makes the worst-case time complexity $O(n)$.
For example, if you want to remove the tail, the time complexity would be $O(n)$. This is because you would need to find the new tail for the queue and since the tail does not have access to the previous element in a singly linked list, you would need to search the entire queue for the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function removeLast() {
// Edge case when there is only 1 element in the queue.
if (head == tail) { // O(1)
value = head.value // O(1)
head = null // O(1)
tail = null // O(1)
return value // O(1)
}
// Searching for the new tail.
newTail = head // O(1)
while (newTail.next != tail) { // O(n)
newTail = newTail.next // O(1)
}
value = tail.value // O(1)
newTail.next = null // O(1)
tail = newTail // O(1)
return tail // O(1)
}
From which can be seen that the time complexity is indeed $O(n)$.
New contributor
$endgroup$
$begingroup$
Enqueue doesn't handle an empty list. While dequeue does handle when the list becomes empty.
$endgroup$
– ratchet freak
3 hours ago
add a comment |
$begingroup$
Enqueueing
You don't need to traverse the entire list to find the new tail, you just need to add a new node where the current tail points to and set that node as the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function enqueue(value) {
node = new Node(value) // O(1)
tail.next = node // O(1)
tail = node // O(1)
size++ // O(1)
}
From which we can conclude that the time complexity is $O(1)$.
Dequeueing
For dequeueing, we only need to set the next node of the current head as the new head and return the value of the old head.
Note: Don't forget that if the new head is set to null
, the tail should be set to null
as well:
Pseudocode (assuming that head != null
and tail != null
):
function dequeue() {
value = head.value // O(1)
head = head.next // O(1)
size-- // O(1)
if (head == null) { // O(1)
tail = null // O(1)
}
return value // O(1)
}
All these operations have $O(1)$ time complexity, which makes the time complexity of the dequeue function $O(1)$ as well.
Searching
Searching for a value is done by traversing through all the items, starting from the head. In the worst case scenario, you would need to traverse the entire queue, which makes the worst-case time complexity $O(n)$.
For example, if you want to remove the tail, the time complexity would be $O(n)$. This is because you would need to find the new tail for the queue and since the tail does not have access to the previous element in a singly linked list, you would need to search the entire queue for the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function removeLast() {
// Edge case when there is only 1 element in the queue.
if (head == tail) { // O(1)
value = head.value // O(1)
head = null // O(1)
tail = null // O(1)
return value // O(1)
}
// Searching for the new tail.
newTail = head // O(1)
while (newTail.next != tail) { // O(n)
newTail = newTail.next // O(1)
}
value = tail.value // O(1)
newTail.next = null // O(1)
tail = newTail // O(1)
return tail // O(1)
}
From which can be seen that the time complexity is indeed $O(n)$.
New contributor
$endgroup$
$begingroup$
Enqueue doesn't handle an empty list. While dequeue does handle when the list becomes empty.
$endgroup$
– ratchet freak
3 hours ago
add a comment |
$begingroup$
Enqueueing
You don't need to traverse the entire list to find the new tail, you just need to add a new node where the current tail points to and set that node as the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function enqueue(value) {
node = new Node(value) // O(1)
tail.next = node // O(1)
tail = node // O(1)
size++ // O(1)
}
From which we can conclude that the time complexity is $O(1)$.
Dequeueing
For dequeueing, we only need to set the next node of the current head as the new head and return the value of the old head.
Note: Don't forget that if the new head is set to null
, the tail should be set to null
as well:
Pseudocode (assuming that head != null
and tail != null
):
function dequeue() {
value = head.value // O(1)
head = head.next // O(1)
size-- // O(1)
if (head == null) { // O(1)
tail = null // O(1)
}
return value // O(1)
}
All these operations have $O(1)$ time complexity, which makes the time complexity of the dequeue function $O(1)$ as well.
Searching
Searching for a value is done by traversing through all the items, starting from the head. In the worst case scenario, you would need to traverse the entire queue, which makes the worst-case time complexity $O(n)$.
For example, if you want to remove the tail, the time complexity would be $O(n)$. This is because you would need to find the new tail for the queue and since the tail does not have access to the previous element in a singly linked list, you would need to search the entire queue for the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function removeLast() {
// Edge case when there is only 1 element in the queue.
if (head == tail) { // O(1)
value = head.value // O(1)
head = null // O(1)
tail = null // O(1)
return value // O(1)
}
// Searching for the new tail.
newTail = head // O(1)
while (newTail.next != tail) { // O(n)
newTail = newTail.next // O(1)
}
value = tail.value // O(1)
newTail.next = null // O(1)
tail = newTail // O(1)
return tail // O(1)
}
From which can be seen that the time complexity is indeed $O(n)$.
New contributor
$endgroup$
Enqueueing
You don't need to traverse the entire list to find the new tail, you just need to add a new node where the current tail points to and set that node as the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function enqueue(value) {
node = new Node(value) // O(1)
tail.next = node // O(1)
tail = node // O(1)
size++ // O(1)
}
From which we can conclude that the time complexity is $O(1)$.
Dequeueing
For dequeueing, we only need to set the next node of the current head as the new head and return the value of the old head.
Note: Don't forget that if the new head is set to null
, the tail should be set to null
as well:
Pseudocode (assuming that head != null
and tail != null
):
function dequeue() {
value = head.value // O(1)
head = head.next // O(1)
size-- // O(1)
if (head == null) { // O(1)
tail = null // O(1)
}
return value // O(1)
}
All these operations have $O(1)$ time complexity, which makes the time complexity of the dequeue function $O(1)$ as well.
Searching
Searching for a value is done by traversing through all the items, starting from the head. In the worst case scenario, you would need to traverse the entire queue, which makes the worst-case time complexity $O(n)$.
For example, if you want to remove the tail, the time complexity would be $O(n)$. This is because you would need to find the new tail for the queue and since the tail does not have access to the previous element in a singly linked list, you would need to search the entire queue for the new tail.
Pseudocode (assuming that head != null
and tail != null
):
function removeLast() {
// Edge case when there is only 1 element in the queue.
if (head == tail) { // O(1)
value = head.value // O(1)
head = null // O(1)
tail = null // O(1)
return value // O(1)
}
// Searching for the new tail.
newTail = head // O(1)
while (newTail.next != tail) { // O(n)
newTail = newTail.next // O(1)
}
value = tail.value // O(1)
newTail.next = null // O(1)
tail = newTail // O(1)
return tail // O(1)
}
From which can be seen that the time complexity is indeed $O(n)$.
New contributor
edited 2 hours ago
Juho
15.5k54191
15.5k54191
New contributor
answered yesterday
AdnanAdnan
2537
2537
New contributor
New contributor
$begingroup$
Enqueue doesn't handle an empty list. While dequeue does handle when the list becomes empty.
$endgroup$
– ratchet freak
3 hours ago
add a comment |
$begingroup$
Enqueue doesn't handle an empty list. While dequeue does handle when the list becomes empty.
$endgroup$
– ratchet freak
3 hours ago
$begingroup$
Enqueue doesn't handle an empty list. While dequeue does handle when the list becomes empty.
$endgroup$
– ratchet freak
3 hours ago
$begingroup$
Enqueue doesn't handle an empty list. While dequeue does handle when the list becomes empty.
$endgroup$
– ratchet freak
3 hours ago
add a comment |
$begingroup$
The comment in the book apparently assumes that your linked list implementation maintains two pointers, head
that points to the first node in the list, and last
that points to the last node.
With this design, appending to the list is simply:
list.last.next = newNode;
list.last = newNode;
But removing the last node requires finding the 2nd to last node, so you can clear its next
link, and change the last
pointer to point to it. This requires scanning the list to find the node where node.next == list.last
.
You could conceivably also have a list.secondToLast
pointer, but that doesn't solve the problem, because when you remove the last node you need to change this to point to the previous third to last node, and this problem recurses to the entire list.
$endgroup$
add a comment |
$begingroup$
The comment in the book apparently assumes that your linked list implementation maintains two pointers, head
that points to the first node in the list, and last
that points to the last node.
With this design, appending to the list is simply:
list.last.next = newNode;
list.last = newNode;
But removing the last node requires finding the 2nd to last node, so you can clear its next
link, and change the last
pointer to point to it. This requires scanning the list to find the node where node.next == list.last
.
You could conceivably also have a list.secondToLast
pointer, but that doesn't solve the problem, because when you remove the last node you need to change this to point to the previous third to last node, and this problem recurses to the entire list.
$endgroup$
add a comment |
$begingroup$
The comment in the book apparently assumes that your linked list implementation maintains two pointers, head
that points to the first node in the list, and last
that points to the last node.
With this design, appending to the list is simply:
list.last.next = newNode;
list.last = newNode;
But removing the last node requires finding the 2nd to last node, so you can clear its next
link, and change the last
pointer to point to it. This requires scanning the list to find the node where node.next == list.last
.
You could conceivably also have a list.secondToLast
pointer, but that doesn't solve the problem, because when you remove the last node you need to change this to point to the previous third to last node, and this problem recurses to the entire list.
$endgroup$
The comment in the book apparently assumes that your linked list implementation maintains two pointers, head
that points to the first node in the list, and last
that points to the last node.
With this design, appending to the list is simply:
list.last.next = newNode;
list.last = newNode;
But removing the last node requires finding the 2nd to last node, so you can clear its next
link, and change the last
pointer to point to it. This requires scanning the list to find the node where node.next == list.last
.
You could conceivably also have a list.secondToLast
pointer, but that doesn't solve the problem, because when you remove the last node you need to change this to point to the previous third to last node, and this problem recurses to the entire list.
answered 17 hours ago
BarmarBarmar
1587
1587
add a comment |
add a comment |
Appe is a new contributor. Be nice, and check out our Code of Conduct.
Appe is a new contributor. Be nice, and check out our Code of Conduct.
Appe is a new contributor. Be nice, and check out our Code of Conduct.
Appe is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Computer Science Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcs.stackexchange.com%2fquestions%2f105029%2fwhat-is-the-time-complexity-of-enqueue-and-dequeue-of-a-queue-implemented-with-a%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
6
$begingroup$
Please do not remove significant information from your question once you have received an answer. We want the pair of question and answer to be useful for others in the future, so try to keep things complete.
$endgroup$
– Discrete lizard♦
18 hours ago