It is important to know whether you want to traverse a linked list in pre order or post order.
Pre-Order Traversal
Iterative style
The logic is very simple:
for(auto p = head; p !=nullptr; p = p->next){// Do something to p.
}
If we need to visit 2 nodes at once (like manipulating the link), use prev pointer to store the last visited node.
ListNode* prev =nullptr;for(auto p = head; p !=nullptr; p = p->next){// Do something to prev, p.
prev = p;}
Recursive style
voiddo_something(ListNode*cur){if(cur ==nullptr){return;}else{// Do something to cur
do_something(cur->next);}}
If 2 nodes are needed inside a loop:
voiddo_something(ListNode*prev, ListNode*cur){if(cur ==nullptr){// Do something at the end
return;}else{// Do something to prev, cur
do_something(cur, cur->next);}}do_something(nullptr, head);
Post-Order Traversal
This type of traversal is only viable through either a stack or recursive functions.
We process the end node first, and go back to the head node one by one.
Iterative style
In order to interatively do the post-order traversal, a stack is needed at the beginning.
auto next = stack<ListNode*>();// First push all nodes to a stack
for(auto p = head; p !=nullptr; p = p->next){ next.push(p);}// Pop one by one
while(!next.empty()){auto p = next.top(); next.pop();// Do something to p
}
If 2 node is needed, you can push a nullptr at the bottom, and check if nullptr is at the top during the loop:
auto next = stack<ListNode*>({nullptr});// First push all nodes to a stack
for(auto p = head; p !=nullptr; p = p->next){ next.push(p);}// Pop one by one
while(next.top()!=nullptr){auto p = next.top(); next.pop();// Do something to p and next.top()
}
Recursive style
You can also do the post order traversal in the recursive style:
voiddo_something(ListNode*cur){if(cur ==nullptr){return;}else{do_something(cur->next);// Do something to cur
}}
Notice the difference between the pre and post order traversal because they are very similar here.
For post-order traversal, we first call the recursive function, then do something to the current node.
2-node post-order traversal:
voiddo_something(ListNode*prev, ListNode*cur){if(cur ==nullptr){return;}else{do_something(cur, cur->next);// Do something to cur, cur->next
}}do_something(nullptr, head);