I am trying to pop elements from the end of a circular linked list in python. All the elements are getting popped successfully, but error arises when only one node is left. When the last remaining node is popped an error occurs. Is there any problem with the show function?
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
class CircularLinkedList(object):
def __init__(self, tail = None):
self.tail = tail
def append(self, value):
new_node = Node(value)
if self.tail ==None:
self.tail = new_node
self.tail.next = new_node
if self.tail!=None:
new_node.next= self.tail.next
self.tail.next=new_node
self.tail= new_node
#pop function
def pop(self):
if self.tail==None:
print("Sorry no elements .")
else:
if self.tail.next==self.tail:
self.tail=None
return self.tail
else:
temp=self.tail.next
while temp.next!=self.tail:
temp=temp.next
temp.next=self.tail.next
removed = self.tail
self.tail=temp
print("Popped")
return removed
#display function
def show(self):
current = self.tail
while current.next:
current = current.next
print(current.value)
if current == self.tail:
break
circular = CircularLinkedList()
circular.append(5)
circular.append(9)
circular.append(96)
print("Before deleting:")
circular.show()
circular.pop()
circular.pop()
circular.pop()
circular.show()
When you pop the last element you assign None
to self.tail
, so in show()
in
while current.next:
you are trying to call next
from None
. Add a check
while current and current.next:
I fixed it so your image shows. The problem is not the popping of the last value. You're doing that correctly. The problem is that your show
function cannot handle an empty list. You need to check for that.
You need to make a little change to you pop
function to understand how many elements got popped.
Like this
def pop(self):
if self.tail==None:
print("Sorry no elements .")
else:
if self.tail.next==self.tail:
self.tail=None
print("popped") #HERE
return self.tail
else:
temp=self.tail.next
while temp.next!=self.tail:
temp=temp.next
temp.next=self.tail.next
removed = self.tail
self.tail=temp
print("Popped")
return removed
This will make things clear for you. And as others said, the reason for your error is in your show
method.
You're making self.tail=None
for the last element in pop()
. And you're trying to access .next
for None
.
Here:
def show(self):
current = self.tail
while current.next:
Add an if
like this to avoid error
def show(self):
current = self.tail
if current.next == None:
print("circular linkedlist is empty")
return None
while current.next:
current = current.next
print(current.value)
if current == self.tail:
break
There are the following issues in your code:
In the pop
method None
is returned when the only remaining node is removed. But it should return the removed node. This happens here:
self.tail=None return self.tail # <-- this will always be None!
Change the pop
function to this:
def pop(self): if not self.tail: print("Sorry no elements.") else: removed = self.tail # also when the only remaining node! if self.tail.next == self.tail: self.tail = None else: temp = self.tail.next while temp.next != self.tail: temp = temp.next temp.next = self.tail.next self.tail = temp print("Popped") return removed
The show
method assumes that the list is not empty. For an empty list it will generate an error on this statement:
while current.next:
So deal with the empty list case separately. Also, it is strange to have this while
condition, as there is a break
inside the loop, that depends on a more useful condition: make that the loop condition. You could write that method as follows:
def show(self): if not self.tail: print("(empty)") return current = self.tail.next while current != self.tail: print(current.value, end=" ") current = current.next print(self.tail.value)
Not an error, but the append
method is a bit weird in how it inserts the first node: it will execute both the if
blocks. It ends up working correctly, but I find that counter-intuitive. It seems better to write this as an if...else
structure, so that exactly one block of code gets executed, not two:
def append(self, value):
new_node = Node(value)
if self.tail:
new_node.next = new_node
else:
new_node.next = self.tail.next
self.tail.next = new_node
self.tail = new_node
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.