2012-01-16 173 views
5

數據結構類,實現具有頭部,尾部和當前節點的單個鏈接列表。遇到方法問題,可以使用正確方向的微調。Java鏈接列表 - 添加方法

從分配,編寫方法:

加(項目)增加了在列表中的當前節點之後的項目(字符串),並將當前的指針指到新節點。

我嘗試:

我add方法似乎只當我將項目添加到列表中,而不是在兩端的工作。如果我用它來添加一些項目然後打印列表,那麼只有我添加的第一個項目會在列表中,而我的prepend和append方法已經測試得很好。

我的代碼有什麼明顯的問題嗎?我覺得我失去了一些明顯的東西。

所有:

public class LinkedList { 
    Node head = null; /* Head of the list */ 
    Node tail = null; /* Tail of the list */ 
    Node curr = null; /* Current node in the list */ 

    public void prepend(String item) { 
     if (head == null) { 
      head = tail = new Node(item, null); 
      curr = head; 
     } else { 
      head = new Node(item, head); 
      curr = head; 
     } 
    } 

    public void append(String item) { 
     if (head == null) { 
      head = tail = new Node(item, null); 
      curr = tail; 
     } else { 
      tail.next = new Node(item, null); 
      tail = tail.next; 
      curr = tail; 
     } 
    } 

    public void add(String item) { 
     if (curr != null) { 
      Node newNode = new Node(item, curr.next); 
      curr.next = newNode; 
      curr = newNode; 
     } else { 
      head = tail = new Node(item, null); 
      curr = head; 
     } 
    } 

    public void delete() { 
     if (curr.next == null) { 
      Node temp = head; 
      while (temp.next != curr) { 
       System.out.println(temp.item); 
       temp = temp.next; 
      } 
      temp.next = null; 
      curr = head; 
     } 
    } 

    public void find(String item) { 
     Node temp = new Node(curr.item, curr.next); 
     if (item.equals(temp.item)) 
      curr = temp; 
     else { 
      temp = temp.next; 
      while (temp.next != null && temp != curr) { 
       if (item.equals(temp.item)) 
        curr = temp; 
      } 
     } 
    } 

    public String get() { 
     if (curr != null) 
      return curr.item; 
     else 
      return ""; 
    } 

    public boolean next() { 
     if (curr != tail) { 
      curr = curr.next; 
      return true; 
     } else 
      return false; 
    } 

    public void start() { 
     curr = head; 
    } 

    public void end() { 
     curr = tail; 
    } 

    public boolean empty() { 
     if (head == null) 
      return true; 
     else 
      return false; 
    } 
} 

Node類:

class Node { 
    Node next; 
    String item; 

    Node(String item, Node next) { 
     this.next = next; 
     this.item = item; 
    } 
} 
+2

其他代碼呢? – fge 2012-01-16 19:47:04

+0

該部分看起來不錯,所以向我們展示周圍的代碼,錯誤必須在那裏。 – 2012-01-16 19:57:33

+0

增加了代碼的其餘部分 – dysania 2012-01-16 19:57:47

回答

0

我認爲這個問題是

if (curr != null) { 
    Node newNode = new Node(item, curr.next); //<-- here (curr.next) 

//and 

Node(String item, Node next) { 
    this.next = next; //<-- here 

嘗試(編輯):

Node newNode = new Node(item, curr); // pass curr to the constructor of Node 
curr = newNode; 
+1

我認爲這會使節點指向自己而不是下一個節點。 – vextorspace 2012-01-16 19:55:36

+1

不,這會斷開連接列表,當前'curr'不會指向插入的節點。 – 2012-01-16 19:56:06

+1

如果你這樣做,你會失去元素之間的聯繫...因爲那麼節點都將指向自己。我認爲他的代碼很好:您首先將當前變量的下一個值分配給新節點,然後讓新節點成爲當前變量。我感覺合理。 – Chnoch 2012-01-16 19:57:17

1

我在這裏沒有看到任何問題,所以我猜這個問題是在其他地方。

好吧,我看到有唯一的問題是在刪除:

public void delete() 
{ 
    Node temp = head; 

    while(temp != null && temp.next != curr) { 
     System.out.println(temp.item); 
     temp=temp.next; 

    } 

    if (temp != null && temp.next != null) { 
     temp.next = temp.next.next; 
    } 
    curr = head; 

} 
+0

嗯,這是我第一次使用提供的驅動程序文件來測試我的代碼,所以也許問題在那裏..謝謝你看雖然。 – dysania 2012-01-16 20:06:10

+0

欣賞幫助,但我已經停止了刪除工作,一旦我意識到add沒有正確測試,還沒有完成測試find方法。 – dysania 2012-01-16 20:17:04

+0

'add'確實存在錯誤,請參閱我的答案(或@ Chnoch's)。 – 2012-01-16 20:28:12

1

我想我已經找到了你的問題。 如果使用append(),則直接在尾部後面添加它。但是,如果您在尾部之後添加了前一個節點,則不會將尾部設置爲新節點。這意味着,一旦你調用append()兩次,你將放棄第一次追加()後添加的所有節點。

簡單的例子:

public static void main(String[] args) { 
    LinkedList list = new LinkedList(); 
    list.add("First add"); 
    list.append("First Append"); 
    list.add("Second add"); 
    list.prepend("First prepend"); 
    list.add("Third add"); 
    list.prepend("Second prepend"); 
    list.add("fourth add"); 
    list.append("Second Append"); 
    list.add("Fifth add"); 
    list.add("Sixth add"); 

    list.start(); 
    do { 
     System.out.println(list.get().toString()); 

    } while (list.next()); 
} 

輸出:

Second prepend 
fourth add 
First prepend 
Third add 
First add 
First Append 
Second Append 

結論: 「第二次加入」 丟失,以及 「五加」 和 「第六次加」 因爲你的next()方法只要到達尾巴就停下來。如果最後添加新節點,則需要始終更新尾部。

希望這會有所幫助。 Cheers,Chnoch

+0

非常有幫助的感謝,將對此工作 – dysania 2012-01-16 20:27:49

5

add確實存在一個問題:當節點已經存在時,它不會更新tail。考慮的行動序列:

public void print() { 
    Node curr = this.head; 
    while(curr != null) { 
     System.out.println(curr.item); 
     curr = curr.next; 
    } 
} 

像這樣::

LinkedList list = new LinkedList(); 
list.add("one"); 
list.add("two"); 
list.append("three"); 

如果你要那麼使用該打印

list.print(); 

你會得到以下輸出:

one 
three 

發生這種情況使用tail - 其中append依賴於 - 繼續執行第二個add操作後指向第一個Node