【问题标题】:How to Create a Circular LinkedList如何创建循环链表
【发布时间】:2015-06-09 05:58:42
【问题描述】:

我知道如何创建 LinkLinearLinkedList 类,但我终生无法弄清楚如何将它们修改为创建 circularlinkedlist

我已经阅读了this question 的答案。但是,我不明白如果headNone,那么None 类型的对象怎么会有next 属性?我似乎无法理解这个概念。

如果有人可以向我展示示例CircularLinkedList__init__ 函数并对其工作原理进行简单解释,我想我将能够理解它。

感谢大家的帮助

编辑:我只需要向前遍历列表。如果是这样,背后的逻辑是否需要彻底改变?

【问题讨论】:

  • 你能画出这样一个包含零、一、二等元素的列表的图表吗?这应该可以帮助您弄清楚如何组织事物。另外,问问自己该列表是否应该只包含一个方向或另一个方向的链接。
  • 我只需要它们单独连接转发。如果我也需要它向后遍历,它会产生巨大的差异吗?
  • 对于绘图来说,这很容易,但是在单链表上的一些操作比在双链表上更复杂。

标签: python singly-linked-list circular-list


【解决方案1】:
            class Node:
                def __init__(self, d=None, n=None, p=None):
                    self.data = d
                    self.next_node = n
                    self.p_node = p
            
                def __str__(self):
                    return '(' + str(self.data) + ')'
            
            
            class CircularlinkedList:
                def __init__(self, r=None):
                    self.root = r
                    self.size = 0
            
                def add(self, d):
                    if self.size == 0:
                        self.root = Node(d)
                        self.root.next_node = self.root
                    else:
                        new_node = Node(d, self.root.next_node)
                        self.root.next_node = new_node
                    self.size += 1
            
                def find(self, d):
                    this_node = self.root
                    while True:
                        if this_node.data == d:
                            return d
                        elif this_node.next_node == self.root:
                            return False
                        this_node = this_node.next_node
            
                def remove(self, d):
                    this_node = self.root
                    prev_node = None
                    while True:
                        if this_node.data == d:
                            if prev_node is not None:
                                prev_node.next_node = this_node.next_node
                            else:
                                while this_node.next_node != self.root:
                                    this_node = this_node.next_node
                                this_node.next_node = self.root.next_node
                                self.root = self.root.next_node
                            self.size -= 1
                            return True
                        elif this_node.next_node == self.root:
                            return False
                        prev_node = this_node
                        this_node = this_node.next_node
            
                def print_list(self):
                    if self.root is None:
                        return
                    this_node = self.root
                    print(this_node, end='->')
                    while this_node.next_node != self.root:
                        this_node = this_node.next_node
                        print(this_node, end='->')
                    print()
            

           

cll = CircularlinkedList()

for i in [5, 7, 3, 8, 9]:

    cll.add(i)

打印('Size='+str(cll.size))

打印(cll.find(8))

打印(cll.find(12))

my_node = cll.root

 for i in range(8):

    my_node = my_node.next_node

    print(my_node,end='->')

打印()

cll.print_list()

cll.remove(8)

打印(cll.remove(15))

打印('Size='+str(cll.size))

cll.remove(5)

cll.print_list()

【讨论】:

    【解决方案2】:
    #Linked List Program to Add and Delete Node Form Head, Tail, in Between Nodes.
    class Node:
        """ Node Class having the data and pointer to the next Node"""
        def __init__(self,value):
            self.value=value
            self.nextnode=None
            
    class CircularLinkedList(object):
        """ Linked List Class to point the value and the next nond"""
        def __init__(self):
            self.head=None
    
        def add_head_node(self,value):
            node=Node(value)
            if self.head is None:
                self.head=node
                self.head.nextnode=self.head
                
            crnt_node=node
            crnt_node.nextnode=self.head        
            first_node=self.head
            while first_node.nextnode is not self.head:
                first_node=first_node.nextnode          
            first_node.nextnode=crnt_node
            self.head=crnt_node
    
        #Adding elements in linked list to the tail.
        def add_tail_node(self,value):
            node=Node(value)
            if self.head is None:
                self.head=node
                self.head.nextnode=self.head
            crnt_node=node
            last_node=self.head
            while last_node.nextnode is not self.head:
                last_node=last_node.nextnode
            #pointing  head's last element to given node
            last_node.nextnode=crnt_node
            #pointing last node next to head nodes of element
            crnt_node.nextnode=self.head
    
        #Adding elements in linked after given Node.
        def add_after_node(self,after_value,value):
            node=Node(value)
            if self.head is None:
                self.head=node
                self.head.nextnode=self.head
            new_node=node
            after_node=Node(after_value)
            head_node=self.head
            while head_node.value !=after_node.value:
                head_node=head_node.nextnode
                last_node=head_node.nextnode
            head_node.nextnode=new_node
            new_node.nextnode=last_node
            head_node=head_node.nextnode
    
        #Adding elements in linked before given Node.
        def add_before_node(self,bfr_value,value):
            node=Node(value)
            if self.head is None:
                self.head=node
                self.head.nextnode=self.head
            new_node=node
            bfr_node=Node(bfr_value)
            head_node=self.head
            while head_node.nextnode.value!=bfr_node.value:
                head_node=head_node.nextnode
                last_node=head_node.nextnode
            head_node.nextnode=new_node
            new_node.nextnode=last_node
            head_node=head_node.nextnode
            #self.head=head_node.nextnode
    
        #deleting Head Node of Linked List
        def del_head_node(self):
            if self.head is None:
                print('Can not delete elements from Empty Linked List')
                return
            crnt_node=self.head.nextnode
            pointer_head=self.head.nextnode
            while pointer_head.nextnode.value!=self.head.value:
                pointer_head=pointer_head.nextnode
            pointer_head.nextnode=crnt_node
            self.head=crnt_node
            
        #deleting tail Node of Linked List
        def del_tail_node(self):
            if self.head is None:
                print('Can not delete elements from Empty Linked List')
                return
            crnt_node=self.head.nextnode
            #head_node=self.head
            while crnt_node.nextnode.nextnode.value!=self.head.value:
                crnt_node=crnt_node.nextnode
            crnt_node.nextnode=self.head
    
        #delete beteween node from Linked List
        def del_bw_node(self,value):
            node=Node(value)
            if self.head is None:
                print('Can not delete elements from Empty Linked List')
                return
            crnt_node=self.head
            while crnt_node.nextnode.value!=node.value:
                crnt_node=crnt_node.nextnode
                last_node=crnt_node.nextnode.nextnode
            crnt_node.nextnode=last_node
    
        #Function to print linked list node 
        def print_list(self):
            crnt_node=self.head
            while True:
                print(f'{crnt_node.value}->',end='')
                if crnt_node.nextnode is self.head:
                    print(f'{self.head.value}',end='')
                    break
                crnt_node = crnt_node.nextnode
            print()
    
    
    cir_llist=CircularLinkedList()
    cir_llist.add_head_node(1)
    cir_llist.print_list()
    cir_llist.add_head_node(2)
    cir_llist.print_list()
    cir_llist.add_head_node(3)
    cir_llist.print_list()
    cir_llist.add_head_node(4)
    cir_llist.print_list()
    cir_llist.add_head_node(5)
    cir_llist.print_list()
    cir_llist.add_tail_node(6)
    cir_llist.print_list()
    cir_llist.add_tail_node(8)
    cir_llist.print_list()
    cir_llist.add_after_node(6,7)
    cir_llist.print_list()
    cir_llist.add_before_node(6,0)
    cir_llist.print_list()
    cir_llist.add_before_node(0,10)
    cir_llist.print_list()
    cir_llist.del_head_node()
    cir_llist.print_list()
    cir_llist.del_head_node()
    cir_llist.print_list()
    cir_llist.del_tail_node()
    cir_llist.print_list()
    cir_llist.del_tail_node()
    cir_llist.print_list()
    cir_llist.del_bw_node(10)
    cir_llist.print_list()
    cir_llist.del_bw_node(0)
    cir_llist.print_list()
    

    【讨论】:

      【解决方案3】:

      通常在循环链表中,您有一个不包含有意义数据的特殊链接。相反,它是一个“哨兵”,让您知道列表的开始(和结束)在哪里。即使列表为空,此链接也会存在,因此您的算法将适用于所有列表,而无需大量特殊情况需要特殊代码。

      class Link:
          def __init__(self, data, next):
              self.data = data
              self.next = next
      
      class CircularLinkedList:
          def __init__(self):
              self.head = Link(None, None) # this is the sentinel node!
              self.head.next = self.head   # link it to itself
      
          def add(self, data):             # no special case code needed for an empty list
              self.head.next = Link(data, self.head.next)
      
          def __contains__(self, data):    # example algorithm, implements the "in" operator
              current = self.head.next
              while current != self.head:
                  if current.data == data: # element found
                      return True
                  current = current.next
              return False
      

      【讨论】:

      • 假设我删除了最后一个链接。它会自动调整以循环到第一个链接,还是我必须在我的删除功能中手动考虑它? * 通过玩弄明白了。感谢您的帮助!
      【解决方案4】:

      确实;如果没有节点,那么就没有下一个/上一个指针:

      root
       |
       v
      None
      

      如果有一个节点,则向后和向前链接到自己:

          root
           |
           v
      +-> Node <-+
      |   next---+
      +---prev
      

      如果有两个节点:

            root
             |
             v
        +-> Node   +-> Node <--+
        |   next---+   next--+ |
      +-|---prev <-----prev  | |
      | +--------------------+ |
      +------------------------+
      

      【讨论】:

      • 您的“无节点”情况并不完全是 OP 描述的情况(尽管这是一种可能的方法)。相反,这与您描述为“一个”节点的情况更相似。不过,您的方法可能是一种更方便的表示,因为它可以让None-tests 更容易。
      • 感谢您的视觉展示。感谢您的帮助!
      【解决方案5】:

      这里的关键步骤是头部不是None。只有head的Link节点的数据是None,通过next属性指向自己。正如您链接到的答案中提到的那样,这看起来像这样:

      def __init__(self):
          self.head = Link(None, None)
          self.head.next = self.head
      

      【讨论】:

      • 我想我开始明白了。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2014-03-06
      • 2021-09-02
      • 2020-10-31
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      相关资源
      最近更新 更多