2015-10-12 10 views
5

Projem için tek tek bağlı bir liste uygulamalıyım ve kaldırma yönteminin çalışmaya başlaması konusunda sorun yaşıyorum. Ben burada cevaplar için arama yaptım ama kuyruk referansı dahil bulamıyorum. Projemin listede bir baş ve kuyruk referansı olması ve gerektiğinde güncellenmesi gerekiyor.Başlık ve kuyruk referansı kullanarak tek başına bağlanan liste kaldırma öğesi

public class BasicLinkedList<T> implements Iterable<T> { 
public int size; 

protected class Node { 
    protected T data; 
    protected Node next; 

    protected Node(T data) { 
     this.data = data; 
     next = null; 
    } 
} 

protected Node head; 
protected Node tail; 

public BasicLinkedList() { 
    head = tail = null; 
} 

public BasicLinkedList<T> addToEnd(T data) { 
    Node n = new Node(data); 
    Node curr = head; 
    //Check to see if the list is empty 
    if (head == null) { 
     head = n; 
     tail = head; 
    } else { 
     while (curr.next != null) { 
      curr = curr.next; 
     } 
     curr.next = n; 
     tail = n; 

    } 
    size++; 
    return this; 
} 

public BasicLinkedList<T> addToFront(T data) { 
    Node n = new Node(data); 
    if(head == null){ 
     head = n; 
     tail = n; 
    } 
    n.next = head; 
    head = n; 
    size++; 
    return this; 
} 

public T getFirst() { 
    if (head == null) { 
     return null; 
    } 
    return head.data; 
} 

public T getLast() { 
    if(tail == null){ 
     return null; 
    } 
    return tail.data; 
} 

public int getSize() { 
    return size; 
} 

public T retrieveFirstElement() { 
    // Check to see if the list is empty 
    if (head == null) { 
     return null; 
    } 
    Node firstElement = head; 
    Node curr = head.next; 
    head = curr; 
    size--; 
    return firstElement.data; 

} 

public T retrieveLastElement() { 
    Node curr = head; 
    Node prev = head; 
    // Check to see if the list is empty 
    if (head == null) { 
     return null; 
    } else { 
     // If there's only one element in the list 
     if (head.next == null) { 
      curr = head; 
      head = null; 
     } else { 
      while (curr.next != null) { 
       prev = curr; 
       curr = curr.next; 
      } 

      tail = prev; 
      tail.next = null; 
     } 
    } 
    size--; 
    return curr.data; 
} 

public void remove(T targetData, Comparator<T> comparator) { 
    Node prev = null, curr = head; 
    while (curr != null) { 
     if (comparator.compare(curr.data, targetData) == 0) { 
      //Check to see if we need to remove the very first element 
      if (curr == head) { 
       head = head.next; 
       curr = head; 
      } 
      //Check to see if we need to remove the last element, in which case update the tail 
      else if(curr == tail){ 
       curr = null; 
       tail = prev; 
       prev.next = null; 
      } 
      //If anywhere else in the list 
      else { 
       prev.next = curr.next; 
       curr = curr.next; 
      } 
      size--; 
     } else { 
      prev = curr; 
      curr = curr.next; 
     } 
    } 
} 

public Iterator<T> iterator() { 
    return new Iterator<T>() { 

     Node current = head; 

     @Override 
     public boolean hasNext() { 
      return current != null; 
     } 

     @Override 
     public T next() { 
      if(hasNext()){ 
       T data = current.data; 
       current = current.next; 
       return data; 
      } 
      return null; 
     } 

     @Override 
     public void remove(){ 
      throw new UnsupportedOperationException("Remove not implemented."); 
     } 

    }; 
} 

}

Ben bu yöntemin birçok tekrarlamalar geçti ve her zaman ben de baş referansı, kuyruk referansı kaybedersem veya çıkarmayın: Bu benim sınıf ve kaldır yöntemidir eleman ve anlamaya çalışıyorum. Buradaki referans, üzerinde çalıştığım test. Testten bile geçemiyorum, sadece başarısızlık izi diyor.

DÜZENLEME: Kaldırma yönteminin, hedef verilerin tüm örneklerini listeden kaldırması gerektiğinden bahsetmiştim.

+0

Son zamanlarda yeni kullanıcılar tarafından soruları size "iyi iş" demek zorunda hissediyorum. bir yorumda. Çok iyi iş! +1 – snickers10m

+1

kodunuzun geri kalanı 'iterator',' getFirst', 'getLast',' addToEnd' –

+0

ekleyin, sorunu kaldırmaya devam etmek istedim ama sanırım sorun başka bir yerde de var olabilir. Artık tüm dersi ekledim. @MarquisBlount –

cevap

2

Sadece 1 hata görüyorum. Başlangıçta aşağıdaki yöntemi boş olduğunu Listeniz bir düğüm sonraki sahip bir döngüye neden olacaksa kendisine başvuran:

public BasicLinkedList<T> addToFront(T data) { 
    Node n = new Node(data); 
    // The list was empty so this if is true 
    if(head == null){ 
     head = n; 
     tail = n; 
    } 
    n.next = head; 
    // now head == n and n.next == head == n so you've got a circle 
    head = n; 
    size++; 
    return this; 
} 

Öyle gibi bu düzeltebilirsiniz:

çok kötü olmuştur
public BasicLinkedList<T> addToFront(T data) { 
    Node n = new Node(data); 
    if(head == null){ 
     tail = n; 
    } 
    n.next = head; 
    head = n; 
    size++; 
    return this; 
} 
+0

Bu sorunu düzeltmek için OP'nin 'if (head == null)' bloğunda 'head = n' öğesini kaldırması yeterlidir. (yolun daha iyi ya da daha kötü olduğunu söylemiyor: P) –

+0

Teşekkür ederim. Onu yakalamadım. –

+0

@AdrianShum evet, bu daha basit bir çözümdür. Cevabımı günceller. –

İlgili konular