class node:
def __init__(self,data):
self.data = data
self.next = None
class circularLL:
def __init__(self):
self.head = None
self.tail = None
def insertNode(self,data):
newnode = node(data)
if self.head is None:
self.head = newnode
self.tail = newnode
else:
newnode.next = self.head
tail = self.tail
tail.next = newnode
self.tail = tail.next
def printCLL(self):
current = self.head
while current.next is not None and current.next is not self.head:
print(current.data, end="----")
current = current.next
print(current.data)
def reverseCLL(self):
head = self.head
tail = self.tail
if head == tail:
return
else:
count = 0
while head.next is not tail:
count =1
if count ==1:
next = head.next
prev = head
head.next = tail
newtail = head
head = next
else:
next = head.next
head.next = prev
prev = head
head = next
if count is not 0:
next = head.next
head.next = prev
prev = head
tail.next = prev
self.head = tail
self.tail = newtail
else:
head.next = tail
self.tail.next = head
self.head = tail
self.tail = head
c = circularLL()
c.insertNode(1)
c.printCLL()
c.insertNode(2)
c.insertNode(3)
c.insertNode(4)
c.insertNode(5)
c.insertNode(6)
c.printCLL()
c.reverseCLL()
c.printCLL()
I have written a code for circular linkedlist. but I think the reverse part can be shorter so how to make the reverse part short ? and what are the alternative to do this ??? and can any one tell me when I am using the assignment operator for a object then that variable is pointing to that original object or the object copy is assign to the variable's memory location ??
CodePudding user response:
There are still some issues in your code:
When the first node is added, that node's
next
reference is left toNone
, which means the list is not really circular. You should actually never have a node whosenext
reference isNone
, so I'd suggest to change theNode
constructor so that it doesn't assign that value, but instead makes the node self referencing (self.next = self
). That also means you can remove most of theNone
checks from your code.The
printCLL
method fails when the list is empty. It should first check that condition.You should not use
is not
when comparing with a literal. So instead doif count != 0:
or evenif count:
Some other remarks:
It is common practice to use PascalCase for class names, so
Node
instead ofnode
andCircularLL
instead ofcircularLL
.As in a circular, non-empty list the head node is always the one after the tail node, there is no real need to store a separate reference to the head node. You just need
self.tail
.As the class name already clearly indicates that we're dealing with a circular linked list, there is no need to have the
CLL
suffix in the method names. And for a similar reason I'd call the insert method justinsert
.Instead of providing a print method, it is probably better practice to provide a
__repr__
method, which the nativeprint
function will call when it exists.Make a linked list instance iterable by defining an
__iter__
method. Then the above__repr__
can also rely on that.
As to the core of your question: yes this code for reversing a list can be greatly reduced. There is no need to have a counter.
Proposed code:
class Node:
def __init__(self,data):
self.data = data
self.next = self
class CircularLL:
def __init__(self):
self.tail = None
def insert(self, data):
newnode = Node(data)
if self.tail:
newnode.next = self.tail.next
self.tail.next = newnode
self.tail = newnode
def __iter__(self):
if not self.tail:
return
current = self.tail
while current.next is not self.tail:
current = current.next
yield current.data
yield current.next.data
def __repr__(self):
return "----".join(map(repr, self))
def reverse(self):
tail = self.tail
if not tail:
return
prev = tail
curr = prev.next
self.tail = curr
while curr != tail:
curr.next, prev, curr = prev, curr, curr.next
curr.next = prev
c = CircularLL()
c.insert(1)
print(c)
c.insert(2)
c.insert(3)
c.insert(4)
c.insert(5)
c.insert(6)
print(c)
c.reverse()
print(c)