2015-04-04 13 views
5

Ich weiß, wie Sie die Link und LinearLinkedList-Klassen erstellen, aber ich kann nicht für das Leben von mir herauszufinden, wie Sie sie in eine Erstellung von Circularlinkedlist ändern. Ich habe die Antwort auf diese Frage bereits gelesen: Help with Circular Linked List in Python. Allerdings verstehe ich nicht, wie wenn der Kopf None ist, wie kann dann ein None-Typ-Objekt ein "next" -Attribut haben? Ich kann das Konzept einfach nicht begreifen. Wenn mir jemand die init Funktion eines Beispiels CircularLinkedList und eine einfache Erklärung, wie es funktioniert, zeigen könnte, würde ich in der Lage sein, es zu verstehen. Danke für jede HilfeSo erstellen Sie eine kreisförmige LinkedList

Edit: Ich brauche nur die Liste nach vorne durchlaufen werden. Wenn dies der Fall ist, wird die Logik dahinter drastisch geändert werden müssen?

+0

Können Sie ein Diagramm für eine solche Liste mit null, eins, zwei etc. Elemente zeichnen? Das sollte dir helfen herauszufinden, wie man etwas organisiert. Fragen Sie sich auch, ob die Liste nur Links in die eine oder die andere Richtung enthalten soll. –

+0

Ich brauche sie nur einzeln vorzuschalten. Ist es ein großer Unterschied, wenn ich es auch rückwärts durchqueren muss? –

+0

Für die Zeichnung ist es einfach, aber einige Operationen in einer einfach verknüpften Liste sind komplizierter als in einer doppelt verknüpften Liste. –

Antwort

5

Oft in einer kreisförmigen verknüpften Liste haben Sie einen speziellen Link, der keine aussagekräftigen Daten enthält. Stattdessen ist es ein "Sentinel", der Sie darüber informiert, wo der Anfang (und das Ende) der Liste ist. Dieser Link wird auch dann existieren, wenn die Liste leer ist, so dass Ihre Algorithmen auf allen Listen funktionieren, ohne viele Spezialfälle, die speziellen Code benötigen.

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 
     return False 
+0

Angenommen, ich lösche den letzten Link. Wird es sich automatisch anpassen, um zum ersten Link zu loopen, oder muss ich es manuell in meiner Löschfunktion berücksichtigen? * Ich habe es herausgefunden, indem ich damit gespielt habe. Danke für die Hilfe! –

0

Der entscheidende Schritt hier ist, dass der Kopf nicht None ist. Nur die Daten des Knotens des Kopfes Link sind None, und er zeigt sich über sein next Attribut. Wie in der Antwort erwähnt, die Sie verbunden haben, würde das in etwa so aussehen:

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

Ich denke, ich fange an, es zu bekommen. Vielen Dank! –

2

In der Tat; Wenn es keine Knoten sind, dann kann es keine nächsten/vorherigen Zeiger sein:

root 
| 
v 
None 

Falls es ein Knoten ist, verbindet sie hin und her auf sich selbst:

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

Wenn es zwei Knoten:

+1

Ihre Situation für 'keine Knoten' ist nicht die Situation, die das OP beschreibt (obwohl es ein möglicher Ansatz ist). Das ähnelt eher der Situation, die Sie als "einen" Knoten beschreiben. Ihre Herangehensweise könnte jedoch eine bequemere Darstellung sein, da sie einfachere 'None'-Tests ermöglicht. – Joost

+0

Vielen Dank für die visuelle Darstellung. Ich schätze die Hilfe! –

Verwandte Themen