Reputation: 10139
I'm working on the problem of print a linked list reversely without destruction. My specific questions are,
O(n)
using recursive call stack;BTW: If there are anything wrong with my current code, like logical bugs, please feel free to advise.
class LinkedListNode:
def __init__(self, value, nextNode):
self.value = value
self.nextNode = nextNode
def print_reverse(self):
if not self.nextNode:
print self.value
return
else:
self.nextNode.print_reverse()
print self.value
if __name__ == "__main__":
head = LinkedListNode('a', LinkedListNode('b', LinkedListNode('c', LinkedListNode('d', None))))
head.print_reverse()
Upvotes: 1
Views: 109
Reputation: 59184
Using O(n) space to print the list in reverse is not very nice, especially if that's stack space.
If you can't modify the list, then you can do it in O(log N) space and O(N log N) time like this:
class LinkedListNode:
def __init__(self, value, nextNode):
self.value = value
self.nextNode = nextNode
def count(list):
ret=0
while list:
ret+=1
list=list.nextNode
return ret
def print_reverse(list,size=-1):
if size<0 and list:
size=count(list)
while size>1:
midpoint=size/2
tail=list
for _ in xrange(midpoint):
tail=tail.nextNode
print_reverse(tail,size-midpoint)
size=midpoint
if size>0:
print list.value
head = tail = LinkedListNode(1,None)
for n in range(2,29):
tail.nextNode=LinkedListNode(n,None)
tail=tail.nextNode
print_reverse(head)
Upvotes: 0
Reputation: 443
If your LinkedListNode
's are not immutable and you are only concerned about the final structure of the linked list, you can reverse the linked list in one iteration, and print the elements while re-reversing it from the end in another iteration; which gives you Ө(1)
space complexity and Ө(n)
time complexity.
Otherwise, if you are not allowed to change any structure at any point, I think Ө(n)
space is the best you can get.
Here is a Java implementation:
class LinkedListNode {
int data;
LinkedListNode next;
LinkedListNode(int data) { this.data = data; }
}
class LinkedListReversePrintImplementation {
static void printReversely(LinkedListNode node) {
LinkedListNode currNode = node,
nextNode = node.next,
temp;
// Remove the link from first node
currNode.next = null;
// Reverse the other links
while (nextNode != null) {
temp = nextNode.next;
nextNode.next = currNode;
currNode = nextNode;
nextNode = temp;
}
// `currNode` now contains the last node
// Initialize the `nextNode` of the reversed linked list
nextNode = currNode.next;
// Remove the first link again
currNode.next = null;
// Print the last node
System.out.println(currNode.data);
// Print the other nodes while re-reversing it
while (nextNode != null) {
System.out.println(nextNode.data);
temp = nextNode.next;
nextNode.next = currNode;
currNode = nextNode;
nextNode = temp;
}
}
}
Upvotes: 2
Reputation: 30268
Your print_reverse()
can be simplified to:
def print_reverse(self):
if self.nextNode:
self.nextNode.print_reverse()
print(self.value)
I don't see how you can improve this, you will need a stack of some description because this list is not doubly linked. But you can use your own stack, which would avoid the risk of recursion overflow:
def print_reverse(self):
stack = [self]
nextNode = self.nextNode
while nextNode:
stack.append(nextNode)
nextNode = nextNode.nextNode
while stack:
print(stack.pop().value)
Upvotes: 2