Reputation: 117
I am currently learning data structures in python and I am having problem in display()
method in CircularDoublyLinkedList
class
The while loop run infinitely by repeating the elements of the CircularDoublyLinkedList
class
#my code:
class Node:
def __init__(self,value):
self.value=value
self.next=None
self.prev=None
class CircularDoublyLinkedList:
def __init__(self):
self.head=None
self.tail=None
def display(self):
if self.head is None:
return 'Circular doubly Linked list doesn\'t exists'
else:
node=self.head
elements=[]
while node:
if node==self.tail:
break
elements.append(node.value)
print(node.value)
node=node.next
return elements
def insertnode(self,value,position):
node=Node(value)
if self.head is None:
self.head=node
self.tail=node
self.prev=node
self.next=node
else:
if position==0:
node.prev=self.tail
node.next=self.head
self.head=node
self.head.prev=node
self.tail.next=node
elif position==-1:
node.next=self.head
node.prev=self.tail
self.tail=node
self.tail.next=node
self.head.prev=node
else:
index=0
tempnode=self.head
while index<position-1:
tempnode=tempnode.next
index+=1
node.next=tempnode.next
node.prev=tempnode
node.next.prev=node
tempnode.next=node
#creating objects
cdll=CircularDoublyLinkedList()
cdll.insertnode(5,0)
cdll.insertnode(0,0)
cdll.insertnode(1,-1)
cdll.insertnode(2,2)
print(cdll.display())
I tried changing the if
condition inside display()
method from node==self.tail
to node==self.tail.next
but nothing changed
So how to resolve this error in display()
method of class CircularDoublyLinkedList
?
any help will be appreciated...thanks
Upvotes: 0
Views: 268
Reputation: 350300
There are several issues:
In display
, the break
should come after you have printed the tail
value. So that loop should look like this:
while node:
elements.append(node.value)
print(node.value)
if node==self.tail:
break
node=node.next
In insertnode
, for the first case, you are assigning to self.prev
and self.next
, but those are not attributes that belong to self
(which is a linked list instance, not a node instance). Instead you want:
node.prev=node
node.next=node
In insertnode
, for the second case, you should not change self.head
before assigning to self.head.prev
. So swap these statements so you get this order:
self.head.prev=node
self.head=node
In insertnode
, for the remaining case, you have a similar issue as in the previous point: first assign to self.tail.next
and only then move the self.tail
reference, so you get this order of execution:
self.tail.next=node
self.tail=node
With those fixes your code will work as expected.
In a circular doubly linked list you don't need a tail reference, because in a non-empty list that self.tail
is always going to be equal to self.head.prev
. So there is really no good reason to maintain it in a separate attribute. Leaving it out makes the code shorter without losing on efficiency.
As no node in a circular doubly linked list has a None
value for either prev
or next
, it is more natural to initialise these attributes with a self-reference in the Node
constructor.
Printing inside a method is not really nice: it mixes the linked-list logic with I/O concerns. Instead, make the linked list iterable by implementing the __iter__
method, and keep the printing in the main program code.
The code for insertnode
can be reduced, by only determining what node.next
must be, and then all the rest of the "wiring" can be common to all cases. The only exception is when a node is added to an empty list.
Applying those points we get this:
class Node:
def __init__(self, value):
self.value = value
self.next = self.prev = self # No None in a doubly linked list
class CircularDoublyLinkedList:
def __init__(self):
self.head = None # No tail needed
def __iter__(self): # iterator is useful for many scenarios
node = self.head
if node:
yield node.value
while node.next != self.head:
node = node.next
yield node.value
def insertnode(self, value, position):
node = Node(value)
if not self.head:
self.head = node # node is already correctly wired
return
node.next = self.head
if position == 0:
self.head = node
while position > 0: # No need for an index variable
node.next = node.next.next
position -= 1
# Common code:
node.prev = node.next.prev
node.prev.next = node.next.prev = node
cdll = CircularDoublyLinkedList()
cdll.insertnode(5, 0)
cdll.insertnode(0, 0)
cdll.insertnode(1, -1)
cdll.insertnode(2, 2)
print(*cdll) # Use iterator for displaying
Upvotes: 1
Reputation: 5519
The loop inside display()
must stop when the next node is the head of the list:
def display(self):
if self.head is None:
return 'Circular doubly Linked list doesn\'t exists'
else:
node=self.head
elements=[]
while node:
elements.append(node.value)
print(node.value)
node=node.next
if node==self.head: break
return elements
Review the method insertnode()
to make sure it is correct! I think it is not working properly.
Upvotes: 1