2015-04-04 22 views
5

So come creare le classi Link e LinearLinkedList, ma non riesco proprio a capire come modificarli in una lista circolare creata. Ho già letto la risposta a questa domanda: Help with Circular Linked List in Python. Tuttavia, non capisco come se la testa sia None, allora come può un oggetto di tipo None avere un attributo "next"? Non riesco proprio ad afferrare il concetto. Se qualcuno può indicarmi la funzione init di un esempio CircularLinkedList e una semplice spiegazione su come funziona, penso che sarei in grado di comprenderlo. Grazie per qualsiasi aiutoCome creare una lista di contatti circolare

Modifica: Ho solo bisogno dell'elenco per essere inoltrato. Se questo è il caso, la logica dietro di esso deve essere drasticamente cambiata?

+0

È possibile disegnare un diagramma per tale elenco con zero, uno, due elementi ecc.? Questo dovrebbe aiutarti a capire come organizzare le cose. Inoltre, chiediti se la lista dovrebbe contenere solo link in una direzione o anche l'altra. –

+0

Ho solo bisogno che siano collegati in avanti singolarmente. Crea una grande differenza se ne ho bisogno anche a ritroso? –

+0

Per il disegno, è facile, ma alcune operazioni su una lista collegata singolarmente sono più complicate che su una lista doppiamente collegata. –

risposta

5

Spesso in un elenco circolare collegato, si dispone di un collegamento speciale che non contiene dati significativi. Invece, è una "sentinella" che ti permette di sapere dov'è l'inizio (e la fine) della lista. Questo link esiste anche quando la lista è vuota, quindi i tuoi algoritmi funzioneranno su tutti gli elenchi, senza molti casi speciali che necessitano di codice speciale.

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

Supponiamo di cancellare l'ultimo collegamento. Regolerà automaticamente il loop sul primo link o dovrò farlo manualmente nella mia funzione di cancellazione? * Capito giocando con esso. Grazie per l'aiuto! –

0

Il passaggio cruciale è che la testina non è None. Solo i dati del nodo Link della testata sono None e puntano su se stesso tramite l'attributo next. Come menzionato nella risposta a cui ci si collegava, sarebbe simile al seguente:

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

Penso che sto iniziando a prenderlo. Grazie! –

2

Infatti; se non ci sono i nodi, quindi non ci può essere nessun prossimi puntatori precedenti /:

root 
| 
v 
None 

Se c'è un nodo, collega avanti e indietro a se stessa:

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

Se ci sono due nodi:

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

La situazione per "nessun nodo" non è esattamente la situazione descritta dall'OP (sebbene sia un possibile approccio). Invece, questo è più strettamente simile alla situazione che descrivi come "un" nodo. Il tuo approccio potrebbe essere una rappresentazione più comoda, tuttavia, poiché consente di semplificare i test di "Nessuno". – Joost

+0

Grazie per la rappresentazione visiva. Apprezzo l'aiuto! –

Problemi correlati