Related
I'm working on a problem that accepts a linked list as input, at this point I don't even know how to set up an example linked list.
My initial problem is understanding the following instruction:
Write a function that accepts a linked list as input, then reverses that linked list.
Does this simply involve defining a 'reversing summary' as part of the following or is there some other way of summarizing a linked lists in Python:
class Node(object):
# Initialize with a single datum and pointer set to None
def __init__(self, data=None, next_node=None):
self.data = data
self.next_node = next_node
# Returns the stored data
def get_data(self):
return self.data
# Returns the next node
def get_next(self):
return self.next_node
# Reset the pointer to a new node
def set_next(self, new_next):
self.next_node = new_next
def set_data(self, data):
self.data = data
class LinkedList(object):
# Top node in the list created on __init__
def __init__(self, head=None):
self.head = head
# Take in the new node and point the new node to the prior head O(1)
def insert(self, data):
new_node = Node(data)
new_node.set_next(self.head)
self.head = new_node
# Counts nodes O(n)
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.get_next()
return count
# Checks each node for requested data O(n)
def search(self, data):
current = self.head
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
current = current.get_next()
if current is None:
raise ValueError("Data not in list")
return current
# Similar to search, leapfrogs to delete, resetting previous node pointer to point to the next node in line O(n)
def delete(self, data):
current = self.head
previous = None
found = False
while current and found is False:
if current.get_data() == data:
found = True
else:
previous = current
current = current.get_next()
if current is None:
raise ValueError("Data not in list")
if previous is None:
self.head = current.get_next()
else:
previous.set_next(current.get_next())
It seems all of the code you have for your base Linked List class is there. You just need to reverse your Linked List. Reversing a linked list is like follows.
[1] -> [2] -> [3] -> NULL
You can tell that 1 is the Head and 3 is the Tail (meaning that it's the last node that is in the linked list because it points to NULL or None in Python). What you need to do is figure out some algorithm that will take that linked list and produce this result.
[3] -> [2] -> [1] -> NULL
Now 3 is the Head and 1 is the Tail.
So using Psuedocode:
Initalize 3 Nodes: prev, next, and current
current = head
prev = None
next = None
While current != None
next = current.next
current.next = prev
prev = current
current = next
head = prev
I've created a linked list in Python, and it is singly linked. This works perfectly fine, but I want to implement it so it's doubly linked, but I'm having trouble figuring out how to do it.
# node class
class node:
def __init__(self):
self.data = None # contains the data
self.next = None # contains the reference to the next node
# linked list class
class linked_list:
def __init__(self):
self.cur_node = None
def add_node(self, data):
new_node = node() # create a new node
new_node.data = data
new_node.next = self.cur_node # link the new node to the 'previous' node.
self.cur_node = new_node # set the current node to the new one.
def list_print(self):
node = self.cur_node # cant point to ll!
while node:
print(node.data)
node = node.next
I know I need to add self.previous to the node class, and I think I need to add something to the linked list constructor and add_node function, but I'm not sure where to start.
I don't actually need to use this functionality in a program, I'm just trying to learn about how linked lists are implemented at a lower level.
It's not so much a coding problem as a conceptual problem. You need to figure out how you want your code to behave. Implementing the desired behavior is not (in this case) at all difficult.
Say we want these behaviors:
# construction
dlist = DoublyLinkedList()
# access to head and tail nodes
dlist.head # should return the head node
dlist.tail # should return the tail node
dlist.head.prev is None # should be True
dlist.tail.next is None # should be True
# adding nodes at both ends
dlist.add_head()
dlist.add_tail()
# iteration in both directions
for node in dlist:
# do something to the node
for node in reversed(dlist):
# do something to the node
When you have written out the desired behavior like this, you'll also have got some test code ready.
Now let's start by modifying the Node class (you should use CamelCase for class names):
class Node:
def __init__(self, data=None, prev=None, next=None):
self.data = data
self.prev = prev
self.next = next
def __repr__(self):
return '<{}, {}>'.format(self.data, self.next)
We add prev since that's obviously needed. But we also improve on your original version by having data and next as parameters, so you can have these values set when a node is created. And __repr__ is always nice to have, for debugging if not for anything else.
Now for the list itself. The key is, (a) instead of one cur_node, you need two handles on the list, which I've been calling head and tail, and (b) when adding nodes, the very first node is a special case where we have to make changes to both head and tail.
class DoublyLinkedList:
def __init__(self):
self.head = None
self.tail = None
def __repr__(self):
return '<DoublyLinkedList {}>'.format(self.head)
def add_head(self, data=None):
if self.head is None:
self.head = self.tail = Node(data) # the very fist node
else:
new_head = Node(data=data, next=self.head) # prev is None
self.head.prev = self.head = new_head
def add_tail(self, data=None):
if self.tail is None:
self.head = self.tail = Node(data) # the very first node
else:
new_tail = Node(data=data, prev=self.tail) # next is None
self.tail.next = self.tail = new_tail
# implements iteration from head to tail
def __iter__(self):
current = self.head
while current is not None:
yield current
current= current.next
# implements iteration from tail to head
def __reversed__(self):
current = self.tail
while current is not None:
yield current
current = current.prev
Let's test this
>>> dlist = DoublyLinkedList()
>>> print(dlist)
<DoublyLinkedList None>
>>> dlist.add_head(1)
>>> dlist.add_tail(2)
>>> dlist.add_tail(3)
>>> dlist.add_head(0)
>>> print(dlist) # __repr__ is such a nice thing to have
<DoublyLinkedList <0, <1, <2, <3, None>>>>>
>>> print(dlist.head)
<0, <1, <2, <3, None>>>>
>>> print(dlist.tail)
<3, None>
>>> print(dlist.head.prev is None, dlist.tail.next is None)
True, True
>>> print(dlist.tail.prev.next is dlist.tail)
True
>>> [node.data for node in dlist]
[0, 1, 2, 3]
>>> for node in reversed(dlist):
... print(node.data, node)
3 <3, None>
2 <2, <3, None>>
1 <1, <2, <3, None>>>
0 <0, <1, <2, <3, None>>>>
For a doubly linked list, you should have, each node should have a reference to the previous node. This means that you will need to modify your add and remove methods to also assign this reference.
I am doing a Python program that implements linked list to support a few functions, one of the functions I need to do is to reverse a stack. I have made a Node, LinkedList and Stack classes, here is my Code so far:
class ListNode:
def __init__(self, Object):
self.Object = Object
self.next = None
class LinkedList:
def __init__(self):
self.head = None # first node
self.tail = None # last node
def addLast(self, Object):
newNode = ListNode(Object)
if self.head == None:
self.head = newNode
self.tail = newNode
else:
self.tail.next = newNode
self.tail = newNode
def removeFirst(self):
if self.head == None:
return
self.head = self.head.next
if self.head == None:
self.tail = None
def removeLast(self, Object):
if self.head == None:
return
current = self.head
prev = None
while current.next != None:
prev = current
current = current.next
if prev == None:
self.head = None
self.tail = None
else:
prev.next = None
self.tail = prev
def get(self, index):
current = self.head
i = 0
while i < index and current != None:
current = current.next
i = i + 1
if current != None and index >= 0:
return current.Object
else:
return None
def size(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.next
return count
def isEmpty(self):
return self.head == None
def printList(self):
if self.head != None:
current = self.head
while current != None:
print(current.Object, end = ' ')
current = current.next
print()
# -------------------- STACK ---------------------------------------------------
class Stack:
# constructor implementation
def __init__(self):
self.llist = LinkedList()
def front(self):
return self.llist.get(0)
def dequeue(self):
self.llist.removeFirst()
def queue(self, Object):
self.llist(Object)
def push(self, Object):
self.llist.addLast(Object)
def pop(self, Object):
self.llist.removeLast(Object)
def printStack(self):
self.llist.printList()
def size(self):
return self.llist.size()
def isEmpty(self):
return self.llist.isEmpty()
# ----------------------- Reverse LIST ------------------------------
def Reverse(S):
# S is a Stack Object
Here is my attempt at the problem:
def rRecursive( self ) :
self._rRecursive( self.head )
def _reverseRecursive( self, n ) :
if None != n:
right = n.next
if self.head != n:
n.next = self.head
self.head = n
else:
n.next = None
self._rRecursive( right )
def Reverse(S):
s.rRecursive()
If this was an ordinary list I could easily reverse it using [::-1] but I cannot since the linkedlist is an object. I was thinking maybe I could use temporary values so I can someone append the beginning of the stack to a list and then somehow convert it back into a stack object.
Edit for duplication: The goal of my program is use an existing Stack and reverse it. The linked post deals with a linked list that was already in a list format.
def get(self, index):
current = self.head
i = 0
while i < index and current != None:
current = current.next
i = i + 1
if current != None and index >= 0:
return current.Object
else:
return None
Edit 2: added my get function.
class Stack:
# constructor implementation
def __init__(self):
self.llist = LinkedList()
def front(self):
return self.llist.get(0)
# push method implementation
def push(self, Object):
self.llist.addLast(Object)
def pop1(self):
self.llist.removeLast1()
def Reverse(S):
new_stack = Stack()
while not S.isEmpty():
new_stack.push(S.front())
S.pop1()
return new_stack
# Current Stack after Push: 12 14 40 13
# Stack after Pop: 12 14 40
# Stack after Reversal: 12 12 12
Edit 3: Added a rework of my code, it returns back a wrong reversal with the first element over and over again.
It's quite easy to reverse a stack using basic stack operations. Pop each item off the old stack and push it onto a new one.
def reverse(stack):
new_stack = Stack()
while not stack.isEmpty():
new_stack.push(stack.front())
stack.pop()
return new_stack
You could do something similar to destructively reverse the LinkedList within the Stack while reusing the stack object itself, you'd just need to use the list operations rather than the stack operations that are aliased to them.
Speaking of stack operations, you'll probably find that your stack performs better if you push and pop from the front, rather than the back. Removing an item from the end of the linked list requires iterating over the whole list (to find the next-to-last node). In contrast, both adding and removing from the front are fast.
You shouldn't have to fiddle with link pointers in your reversal function. I assume that you have a pop() method and other basics with your stack; if not, then clone your removeFirst function to return the removed node.
Now, the recursive function is simple: pop the head of the list, reverse the remaining stack (if any), and add the popped node to the end. Does this handle your problem?
def reverseStack(self):
move_me = self.pop()
if not self.isEmpty():
return (self.reverseStack()).addLast(move_me)
else:
new_stack = Stack()
return new_stack.addLast(move_me)
Other approaches to solving this problem: Cheat.
Define a __iter__ method (which makes sense in any event; iteration is a core Python behavior) to make your type iterable. Simple example:
def __iter__(self):
cur = self.head
while cur is not None:
yield cur.Object
cur = cur.next
Then just do:
values = list(self) # Creates a list containing the current set of values
self.head = self.tail = None # Clear existing linked list
# Add back all the values in reverse order
for value in reversed(values):
self.addLast(value)
Sure, it's likely less efficient in memory allocation/deallocation overhead than doing it properly. But the effect is likely marginal, and it simplifies the implementation code dramatically.
Of course, doing it properly isn't that hard, it's just slightly more confusing (totally untested, but it should be close to right):
def reverse(self):
# Start at beginning, which will be new end
cur, last = self.head, None
# Reverse head and tail pointers in advance
self.head, self.tail = self.tail, self.head
# Traverse while reversing direction of each node pointer
while cur is not None:
# Tuple pack and unpack allows one-line variable swap
cur.next, cur, last = last, cur.next, cur
The usual algorithm for reversing things using basic data structures is to use the fact that a stack is a first in last out data structure. That means if you pop until the stack is empty, you will get the items in the opposite order you pushed them on.
But it looks like you want to do this via recursive functions rather than an explicit stack - in this case, your function would normally fetch the front element,then recurse on the rest of the data structure, then handle that first element. This gets all the elements off in order, but handles them in the opposite order as each recursive call finishes and you work your way back up the call stack. If you neex to add the elements to a reversed data structure (and not just print them), you can build it up via return values by noticing that once you have the reverse if everything after the current element, you just need to attach that element to the front and you have the reverse of everything you were handed.
class Node(object):
def __init__(self, data=None, next_node=None):
self.data = data
self.next = next_node
def Reverse(head):
if head == None :
return None
elif head.next == None :
return head # returns last element from stack
else :
temp = head.next # stores next element while moving forward
head.next = None # removes the forward link
li = Reverse(temp) # returns the last element
temp.next = head # now do the reverse link here
return li
def main() :
temp4 = Node(4,None)
temp3 = Node(3,temp4)
temp2 = Node(2,temp3)
head = Node(1,temp2)
res = Reverse(head)
while res != None :
print(res.data)
res = res.next
main()
I am making a linkedlist, and I had to add in some different functions such as max, min , count and index for my list. I now have to add a remove function which is this snippet of code.
def removeItem(self, position):
''' removeItem removes a selected, because python has a built in "garbage remover",
you don't have to physically delete the node, you only have to skip that node link and python will destroy it
by it self.'''
currentNode = self.head
previousNode = None
count = 0
while count != position:
#This is a quick check to make sure the next node isn't empty.
if currentNode.link is None:
print("Position Invalid")
return None
previousNode = currentNode
currentNode = currentNode.link
count += 1
#Node.Link should link to the next node in the sequence.
previousNode.link = currentNode.link
return currentNode
I am basically just trying to link over the next node in the sequence, so that the built-in garbage remover will remove that node from the sequence. However, I am getting the following error message, which I know has to do something with my instance.
C:\Python33\python.exe "C:/Users/koopt_000/Desktop/College/Sophomore Semester 2/Computer Science 231/Chapter4/Test.py"
900
1
1
2
<ListNode.ListNode object at 0x0000000002679320>
Process finished with exit code 0
Why is it printing out this weird ListNode.ListNode object at the end?
Here is my testing code:
from ListNode import ListNode
from LinkedList import LinkedList
node1 = ListNode(1)
node2 = ListNode(900)
node3 = ListNode(3)
node4 = ListNode(99)
node1.link = node2
node2.link = node3
node3.link = node4
linked_list = LinkedList((1, 900, 3, 99))
print(linked_list.__max__())
print(linked_list.__min__())
print(linked_list.getCount(900))
print(linked_list.getIndex(3))
print(linked_list.removeItem(3))
This is my code for my ListNode class:
# ListNode.py
class ListNode(object):
def __init__(self, item = None, link = None):
'''creates a ListNode with the specified data value and link
post: creates a ListNode with the specified data value and link'''
self.item = item
self.link = link
This is my code for my LinkedList class:
from ListNode import ListNode
class LinkedList(object):
#--------------------------------------------------------------
def __init__(self, seq=()):
""" Pre: Creates a Linked List
Post: Creates a list containing the items in the seq=()"""
if seq == ():
# If there is no items to be put into the list, then it creates an empty one.
self.head = None
else:
# Creates a node for the first item.
self.head = ListNode(seq[0], None)
# If there are remaining items, then they're added while keeping track of the last node.
last = self.head
for item in seq[1:]:
last.link = ListNode(item, None)
last = last.link
self.size = len(seq)
#-------------------------------------------------------------
def __len__(self):
'''Pre: Nothing.
Post: Returns the number of items in the list.'''
return self.size
#-------------------------------------------------------------
def __max__(self):
''' Goes through each node and compares what the max is for the linked list.
Post: Finds the max of the linked list and returns that value.'''
if self.head is None:
return None
max_value = self.head.item
node = self.head.link
while node is not None:
if node.item > max_value:
max_value = node.item
node = node.link
return max_value
#--------------------------------------------------------------
def __min__(self):
''' Goes through each node and compares what the min is for the linked list.
Post: Finds the min of the linked list and returns that value.'''
if self.head is None:
return None
min_value = self.head.item
node = self.head.link
while node is not None:
if node.item < min_value:
min_value = node.item
node = node.link
return min_value
#--------------------------------------------------------------
def getCount(self, yourData):
''' This function counts the amount of times a certain item is in the Linked List.'''
count = 0
node = self.head
for i in range(self.size):
data = node.item
if data is yourData:
count += 1
node = node.link
return count
#--------------------------------------------------------------
def getIndex(self, yourData):
''' getIndex finds the index of the selected item and returns that value. '''
node = self.head
if node is None:
return None
for i in range(self.size):
data = node.item
if data == yourData:
return i
node = node.link
raise IndexError
#--------------------------------------------------------------
def removeItem(self, position):
''' removeItem removes a selected, because python has a built in "garbage remover",
you don't have to physically delete the node, you only have to skip that node link and python will destroy it
by it self.'''
currentNode = self.head
previousNode = None
count = 0
while count != position:
#This is a quick check to make sure the next node isn't empty.
if currentNode.link == None:
print("Position Invalid")
return None
previousNode = currentNode
currentNode = currentNode.link
count += 1
#Node.Link should link to the next node in the sequence.
previousNode.link = currentNode.link
return currentNode
#--------------------------------------------------------------
If anyone could help me out to find out why my removeItem function isn't working that would be helpful!
On a side note, I'm also trying to make a doubly linked list of this list, I know I need to add a prev_node function into my ListNode function, but what else do I need to add? Thanks again!
If your method is returning a <LinkNode object at 0xmemoryaddr> string then it is working fine. You are printing the removed node, and Python is using the default repr() representation for that instance.
If you wanted to make it more readable, you could give the ListNode a object.__repr__ method:
def __repr__(self):
next = 'None' if not self.link else '...' # just to indicate
return 'ListNode({!r}, {})'.format(self.item, next)
This then will print ListNode(99, None) instead of the <ListNode object at 0xmemoryaddr> string Python defaulted to:
>>> ll = LinkedList((1, 900, 3, 99))
>>> ll.head
ListNode(1, ...)
>>> ll.head.link
ListNode(900, ...)
>>> ll.head.link.link
ListNode(3, ...)
>>> ll.head.link.link.link
ListNode(99, None)
One thing you do have to take into account: you need to adjust the length of the list too; on successful removal, subtract 1 from self.size.
I am asked to reverse a which takes head as parameter where as head is a linked list e.g.: 1 -> 2 -> 3 which was returned from a function already defined I tried to implement the function reverse_linked_list in this way:
def reverse_linked_list(head):
temp = head
head = None
temp1 = temp.next
temp2 = temp1.next
temp1.next = None
temp2.next = temp1
temp1.next = temp
return temp2
class Node(object):
def __init__(self,value=None):
self.value = value
self.next = None
def to_linked_list(plist):
head = None
prev = None
for element in plist:
node = Node(element)
if not head:
head = node
else:
prev.next = node
prev = node
return head
def from_linked_list(head):
result = []
counter = 0
while head and counter < 100: # tests don't use more than 100 nodes, so bail if you loop 100 times.
result.append(head.value)
head = head.next
counter += 1
return result
def check_reversal(input):
head = to_linked_list(input)
result = reverse_linked_list(head)
assert list(reversed(input)) == from_linked_list(result)
It is called in this way: check_reversal([1,2,3]). The function I have written for reversing the list is giving [3,2,1,2,1,2,1,2,1] and works only for a list of length 3. How can I generalize it for a list of length n?
The accepted answer doesn't make any sense to me, since it refers to a bunch of stuff that doesn't seem to exist (number, node, len as a number rather than a function). Since the homework assignment this was for is probably long past, I'll post what I think is the most effective code.
This is for doing a destructive reversal, where you modify the existing list nodes:
def reverse_list(head):
new_head = None
while head:
head.next, head, new_head = new_head, head.next, head # look Ma, no temp vars!
return new_head
A less fancy implementation of the function would use one temporary variable and several assignment statements, which may be a bit easier to understand:
def reverse_list(head):
new_head = None # this is where we build the reversed list (reusing the existing nodes)
while head:
temp = head # temp is a reference to a node we're moving from one list to the other
head = temp.next # the first two assignments pop the node off the front of the list
temp.next = new_head # the next two make it the new head of the reversed list
new_head = temp
return new_head
An alternative design would be to create an entirely new list without changing the old one. This would be more appropriate if you want to treat the list nodes as immutable objects:
class Node(object):
def __init__(self, value, next=None): # if we're considering Nodes to be immutable
self.value = value # we need to set all their attributes up
self.next = next # front, since we can't change them later
def reverse_list_nondestructive(head):
new_head = None
while head:
new_head = Node(head.value, new_head)
head = head.next
return new_head
I found blckknght's answer useful and it's certainly correct, but I struggled to understand what was actually happening, due mainly to Python's syntax allowing two variables to be swapped on one line. I also found the variable names a little confusing.
In this example I use previous, current, tmp.
def reverse(head):
current = head
previous = None
while current:
tmp = current.next
current.next = previous # None, first time round.
previous = current # Used in the next iteration.
current = tmp # Move to next node.
head = previous
Taking a singly linked list with 3 nodes (head = n1, tail = n3) as an example.
n1 -> n2 -> n3
Before entering the while loop for the first time, previous is initialized to None because there is no node before the head (n1).
I found it useful to imagine the variables previous, current, tmp 'moving along' the linked list, always in that order.
First iteration
previous = None
[n1] -> [n2] -> [n3]
current tmp
current.next = previous
Second iteration
[n1] -> [n2] -> [n3]
previous current tmp
current.next = previous
Third iteration
# next is None
[n1] -> [n2] -> [n3]
previous current
current.next = previous
Since the while loop exits when current == None the new head of the list must be set to previous which is the last node we visited.
Edited
Adding a full working example in Python (with comments and useful str representations). I'm using tmp rather than next because next is a keyword. However I happen to think it's a better name and makes the algorithm clearer.
class Node:
def __init__(self, value):
self.value = value
self.next = None
def __str__(self):
return str(self.value)
def set_next(self, value):
self.next = Node(value)
return self.next
class LinkedList:
def __init__(self, head=None):
self.head = head
def __str__(self):
values = []
current = self.head
while current:
values.append(str(current))
current = current.next
return ' -> '.join(values)
def reverse(self):
previous = None
current = self.head
while current.next:
# Remember `next`, we'll need it later.
tmp = current.next
# Reverse the direction of two items.
current.next = previous
# Move along the list.
previous = current
current = tmp
# The loop exited ahead of the last item because it has no
# `next` node. Fix that here.
current.next = previous
# Don't forget to update the `LinkedList`.
self.head = current
if __name__ == "__main__":
head = Node('a')
head.set_next('b').set_next('c').set_next('d').set_next('e')
ll = LinkedList(head)
print(ll)
ll.revevse()
print(ll)
Results
a -> b -> c -> d -> e
e -> d -> c -> b -> a
Here is a way to reverse the list 'in place'. This runs in constant time O(n) and uses zero additional space.
def reverse(head):
if not head:
return head
h = head
q = None
p = h.next
while (p):
h.next = q
q = h
h = p
p = h.next
h.next = q
return h
Here's an animation to show the algorithm running.
(# symbolizes Null/None for purposes of animation)
Node class part borrowed from interactive python.org: http://interactivepython.org/runestone/static/pythonds/BasicDS/ImplementinganUnorderedListLinkedLists.html
I created the reversed function.
All comments in the loop of reverse meant for 1st time looping. Then it continues.
class Node():
def __init__(self,initdata):
self.d = initdata
self.next = None
def setData(self,newdata):
self.d = newdata
def setNext(self,newnext):
self.next = newnext
def getData(self):
return self.d
def getNext(self):
return self.next
class LinkList():
def __init__(self):
self.head = None
def reverse(self):
current = self.head >>> set current to head(start of node)
previous = None >>> no node at previous
while current !=None: >>> While current node is not null, loop
nextt = current.getNext() >>> create a pointing var to next node(will use later)
current.setNext(previous) >>> current node(or head node for first time loop) is set to previous(ie NULL), now we are breaking the link of the first node to second node, this is where nextt helps(coz we have pointer to next node for looping)
previous = current >>> just move previous(which was pointing to NULL to current node)
current = nextt >>> just move current(which was pointing to head to next node)
self.head = previous >>> after looping is done, (move the head to not current coz current has moved to next), move the head to previous which is the last node.
You can do the following to reverse a singly linked list (I assume your list is singly connected with each other).
First you make a class Node, and initiate a default constructor that will take the value of data in it.
class Node:
def __init__(self, data):
self.data = data
self.next = None
This solution will reverse your linked list "iteratively".
I am making a class called SinglyLinkedList which will have a constructor:
class SinglyLinkedList:
def __init__(self):
self.head = None
then I have written a method to reverse the list, print the length of the list, and to print the list itself:
# method to REVERSE THE LINKED LIST
def reverse_list_iterative(self):
prev = None
current = self.head
following = current.next
while (current):
current.next = prev
prev = current
current = following
if following:
following = following.next
self.head = prev
# Method to return the length of the list
def listLength(self):
count = 0
temp = self.head
while (temp != None):
temp = temp.next
count += 1
return count
# Method to print the list
def printList(self):
if self.head == None:
print("The list is empty")
else:
current_node = self.head
while current_node:
print(current_node.data, end = " -> ")
current_node = current_node.next
if current_node == None:
print("End")`
After that I hard code the list, and its contents and then I link them
if __name__ == '__main__':
sll = SinglyLinkedList()
sll.head = Node(1)
second = Node(2)
third = Node(3)
fourth = Node(4)
fifth = Node(5)
# Now linking the SLL
sll.head.next = second
second.next = third
third.next = fourth
fourth.next = fifth
print("Length of the Singly Linked List is: ", sll.listLength())
print()
print("Linked List before reversal")
sll.printList()
print()
print()
sll.reverse_list_iterative()
print("Linked List after reversal")
sll.printList()
Output will be:
Length of the Singly Linked List is: 5
Linked List before reversal 1 -> 2 -> 3 -> 4 -> 5 -> End
Linked List after reversal
5 -> 4 -> 3 -> 2 -> 1 -> End
I tried a different approach, in place reversal of the LList.
Given a list 1,2,3,4
If you successively swap nearby nodes,you'll get the solution.
len=3 (size-1)
2,1,3,4
2,3,1,4
2,3,4,1
len=2 (size-2)
3,2,4,1
3,4,2,1
len=1 (size-3)
4,3,2,1
The code below does just that. Outer for loop successively reduces the len of list to swap between. While loop swaps the data elements of the Nodes.
def Reverse(head):
temp = head
llSize = 0
while temp is not None:
llSize += 1
temp = temp.next
for i in xrange(llSize-1,0,-1):
xcount = 0
temp = head
while (xcount != i):
temp.data, temp.next.data = temp.next.data, temp.data
temp = temp.next
xcount += 1
return head
This might not be as efficient as other solutions, but helps to see the problem in a different light. Hope you find this useful.
Here is the whole thing in one sheet. Contains the creation of a linked list, and code to reverse it.
Includes an example so you can just copy and paste into an idle .py file and run it.
class Node(object):
def __init__(self, value, next=None):
self.value = value
self.next = next
def reverse(head):
temp = head
llSize = 0
while temp is not None:
llSize += 1
temp = temp.next
for i in xrange(llSize-1,0,-1):
xcount = 0
temp = head
while (xcount != i):
temp.value, temp.next.value = temp.next.value, temp.value
temp = temp.next
xcount += 1
return head
def printnodes(n):
b = True
while b == True:
try:
print n.value
n = n.next
except:
b = False
n0 = Node(1,Node(2,Node(3,Node(4,Node(5,)))))
print 'Nodes in order...'
printnodes(n0)
print '---'
print 'Nodes reversed...'
n1 = reverse(n0)
printnodes(n1)
def reverseLinkedList(head):
current = head
previous = None
nextNode = None
while current:
nextNode = current.nextNode
current.nextNode = previous
previous = current
current = nextNode
return previous
Most previous answers are correct but none of them had the complete code including the insert method before and and after the reverse so you could actually see the outputs and compare. That's why I'm responding to this question. The main part of the code of course is the reverse_list() method.
This is in Python 3.7 by the way.
class Node(object):
def __incurrent__(self, data=None, next=None):
self.data = data
self.next = next
class LinkedList(object):
def __incurrent__(self, head=None):
self.head = head
def insert(self, data):
tmp = self.head
self.head = Node(data)
self.head.next = tmp
def reverse_list(self):
current = self.head
prev = None
while current :
#create tmp to point to next
tmp = current.next
# set the next to point to previous
current.next = prev
# set the previous to point to current
prev = current
#set the current to point to tmp
current = tmp
self.head = prev
def print(self):
current = self.head
while current != None:
print(current.data,end="-")
current = current.next
print(" ")
lk = LinkedList()
lk.insert("a")
lk.insert("b")
lk.insert("c")
lk.print()
lk.reverse_list()
lk.print()
output:
c-b-a-
a-b-c-
Following is the generalized code to reverse a singly linked list, where head is given as function's argument:
def reverseSll(ll_head):
# if head of the linked list is empty then nothing to reverse
if not ll_head:
return False
# if only one node, reverse of one node list is the same node
if not ll_head.next:
return ll_head
else:
second = ll_head.next # get the second node of the list
ll_head.next = None # detach head node from the rest of the list
reversedLL = reverseSll(second) # reverse rest of the list
second.next = ll_head # attach head node to last of the reversed list
return reversedLL
Let me explain what I am doing here:
1) if head is null or head.next is null(only one node left in the list) return node
2) else part: take out 1st node, remove its link to rest of the list, reverse rest of the list(reverseSll(second)) and add 1st node again at last and return the list
Github link for the same
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList :
def __init__(self):
self.head = None
def add(self, data):
node = Node(data)
if not self.head:
self.head = node
else:
current = self.head
while current.next != None:
current = current.next
current.next = node
def printList(self):
value = []
if not self.head:
print("liss is Empty")
else:
current = self.head
while current:
value.append(current.data)
current = current.next
print(value)
# this func start reverse list from the last to first
def reverseLinkedList(self,node1,node2):
if self.head == None:
print("list Empty")
else:
# when we reach the last of list we link head with the last element and we disconnect head with second element that will make first element in the last of the list
if node2 == None and node1 != None:
self.head.next = None
self.head = node1
return
else:
self.reverseLinkedList(node1.next, node2.next )
node2.next = node1
ln = LinkedList()
ln.add(1)
ln.add(2)
ln.add(3)
ln.add(4)
ln.add(5)
ln.add(6)
ln.add(7)
ln.add(8)
ln.add(9)
ln.printList()
ln.reverseLinkedList(ln.head,ln.head.next)
print("after first reverse")
ln.printList()
# after i reverse list I add new item to the last
ln.add(0)
print("after add new element to the last of the list")
ln.printList()
print("after second reverse")
# i made second reverse to check after I add new element if my function work perfectly
ln.reverseLinkedList(ln.head,ln.head.next)
ln.printList()
Output :
[1, 2, 3, 4, 5, 6, 7, 8, 9]
after first reverse
[9, 8, 7, 6, 5, 4, 3, 2, 1]
after add new element to the last of the list
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
after second reverse
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Efficient way to reverse linkedlist is discussed in the below steps. Approach to reverse the linking.
Use a variable curr and equal it to head.
Use a variable prev and equal it to None.
Apply the loop with the condition that loop will run till curr is not None and in this condition use another variable next which is equal to curr.next. This will be used to get hold of next node. Now make curr.next = prev. In this way the head after reversing linkedlist will point to None. Now make prev = curr and curr = next
Code snippet
def reverse_linked_list(head):
# corner case
if head == None:
return
curr = head
# reason being orginal head after reversing should point to None
prev = None
while curr is not None:
next = curr.next
curr.next = prev
prev = curr
curr = next
# prev is returned because both curr and next will be None after reversing
return prev
There is another way to perform the task which will take time complexity as theta(n) and space complexity as theta(n). This is a recursive solution and steps are as below
Step 1: Apply the recursion for n -1 node from the end side. This means reverse the list leaving the first node.
Step 2: Link the first node with all nodes obtained from step 1 in reverse order
Code
def reverse_linked_list_recursion(head):
# corner case
if head == None:
return
if head.next == None:
return head
rest_head = reverse_linked_list_recursion(head.next)
rest_tail = head.next
rest_tail.next = head
head.next = None
return rest_head
U can use mod function to get the remainder for each iteration and obviously it will help reversing the list . I think you are a student from Mission R and D
head=None
prev=None
for i in range(len):
node=Node(number%10)
if not head:
head=node
else:
prev.next=node
prev=node
number=number/10
return head