Home > Software design >  how to make this code short for reverse circular LL in python
how to make this code short for reverse circular LL in python

Time:06-05

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 to None, which means the list is not really circular. You should actually never have a node whose next reference is None, so I'd suggest to change the Node 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 the None 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 do if count != 0: or even if count:

Some other remarks:

  • It is common practice to use PascalCase for class names, so Node instead of node and CircularLL instead of circularLL.

  • 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 just insert.

  • Instead of providing a print method, it is probably better practice to provide a __repr__ method, which the native print 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)
  • Related