Reputation: 189
How would I write a pop()
method for LinkedStack in O(1)?
I have two private data members in my LinkedStack
class: ListNode* head
and ListNode* tail
.
head
points to the beginning of the LinkedStack
, and tail
points to the end of the LinkedStack
.
pop()
will remove the ListNode
being pointed to by tail
, then tail
will point to the ListNode
that was before tail
.
Knowing this, how would I write pop()
in O(1)
? Obviously, I can write a for loop that grabs the previous ListNode
right before tail
, but then pop()
wouldn't be O(1)
.
Since this is for homework, I'm not looking for code solutions, just maybe a hint in the right direction.
Edit: One solution I possibly see is having a ListNode* prev
data member, which always points to the previous ListNode before tail
. But I feel like there's a more efficient way....
Edit2: Thanks @user4581301. Assume that pop()
will not be called when LinkedStack
is empty.
Upvotes: 1
Views: 607
Reputation: 881643
As you state, any situation where you have to traverse the list to locate a specific element is going to make the constant time requirement impossible to meet. This includes a singly-linked list where you're pushing items on to the end. A doubly-linked list will be easier since you can then get from the tail to the penultimate item without traversal.
However, I'm not sure why you're pushing on to the end. If you were to push new elements on the the front of the list, achieving constant time for both push
and pop
is trivial.
By that, I mean (pseudo-code since, as you mention, "this is for homework"):
def push(x):
allocate node # get new node and set data.
node.data = x
node.next = head # insert at head of list
head = node
def pop():
assert head != null # catch pop on empty stack
node = head # get first node and data
retval = node.data
head = head.next # set head to be second node
free node # free node and return data
return retval
You can see that there is no traversal of the list for either operation. First, pushing 7
on to a stack of primes:
Starting list:
head
\
5 -> 3 -> 2 -|
Create new node, point to current head:
head
\
7 -> 5 -> 3 -> 2 -|
Point head at new node:
head
\
7 -> 5 -> 3 -> 2 -|
Now let's pop that same value.
Starting list:
head
\
7 -> 5 -> 3 -> 2 -|
Save head as node, and value to return (7):
head
\
7 -> 5 -> 3 -> 2 -|
/
node
Adjust head:
head
\
7 -> 5 -> 3 -> 2 -|
/
node
Free node and return stored value (7):
head
\
5 -> 3 -> 2 -|
Upvotes: 3