2009-12-06 26 views
2

我正在用Java實現我自己的鏈表。節點類只有一個名爲「name」的字符串字段和一個名爲「link」的節點。現在我有一個測試驅動程序類,它只能順序插入幾個名字。現在,我正在嘗試編寫一個排序方法來按字母順序排列節點,但是我遇到了一些麻煩。我從別人的帖子中發現了這個冒泡的僞代碼,並試圖實現它,但是它沒有完全分類條目。我不太清楚爲什麼。任何建議表示讚賞!用Java手動排序鏈表(詞法)

private void sort() 
    { 
     //Enter loop only if there are elements in list 
     boolean swapped = (head != null); 

     // Only continue loop if a swap is made 
     while (swapped) 
     { 
      swapped = false; 

      // Maintain pointers 
      Node curr = head; 
      Node next = curr.link; 
      Node prev = null; 

      // Cannot swap last element with its next 
      while (next != null) 
      { 
       // swap if items in wrong order 
       if (curr.name.compareTo(next.name) < 0) 
       { 
        // notify loop to do one more pass 
        swapped = true; 

        // swap elements (swapping head in special case 
        if (curr == head) 
        { 
         head = next; 
         Node temp = next.link; 
         next.link = curr; 
         curr.link = temp; 
         curr = head; 
        } 
        else 
        { 
         prev.link = curr.link; 
         curr.link = next.link; 
         next.link = curr; 
         curr = next; 
        } 
       } 

       // move to next element 
       prev = curr; 
       curr = curr.link; 
       next = curr.link; 
      } 
     } 
    } 
+0

對於它的價值,我認爲比較中的「<」會讓你的排序進入DESCENDING順序。 – 2009-12-06 09:42:41

+0

你能給一個「不完全排序條目」的例子嗎? - 你的bubblesort代碼看起來不錯 – 2009-12-06 10:26:39

回答

3

我花了幾分鐘時間查看錯誤代碼,但沒有發現任何錯誤。

我會說,直到有人更聰明或更辛苦的工作出現,你應該嘗試自己調試。如果你有像Eclipse這樣的IDE,你可以單步執行代碼,同時觀察變量的值;如果沒有,您可以在幾個地方插入打印語句,並用您的預期手工檢查您看到的內容。


更新我

我複製你的代碼,並進行了測試。除了它按降序排列(這可能不是你想要的),它對於0,1和10個隨機節點的樣本來說是完美的。那麼問題在哪裏?

UPDATE II

還在猜測什麼可以通過以下方式指的是「它沒有完全排序的條目。」您可能期望進行詞典排序(即'B'之前的'a'),並且不會按照計劃混合使用大寫/小寫字詞。這種情況下的解決方案是使用String方法compareToIgnoreCase(String str)

+0

「compareToIgnoreCase(String str)」 這正是我的問題的解決方案。不幸的是,我沒有注意到我的一些測試數據是混合大小寫的......我不相信我忽略了那麼簡單的東西。此外,我確實將比較改爲「> 0」以便升序排列,謝謝! – Aaron 2009-12-06 17:05:04

+1

很好,我的毅力得到了回報。哦,等等,它沒有:沒有接受,沒有upvote。沒有花,我敢打賭,你甚至不會打電話給我!*嗅探* – 2009-12-06 17:15:10

+1

呵呵,忘記接受...我沒有花,但我最近遺傳了很多糖果:3 – Aaron 2009-12-06 17:28:24

0

這可能不是您正在尋找的解決方案,但它很好,很簡單。也許你像我一樣懶惰。

由於您的節點只包含單個數據項,您並不需要重新洗牌您的節點;您可以簡單地交換節點上的值,同時保持列表結構本身不受干擾。

這樣,你可以自由地實現泡泡分類很簡單。

+0

是的,這可能是這樣做的最簡單的方法,但我想我自己的滿意度,我希望能夠知道如何度假節點本身。 – Aaron 2009-12-06 17:16:21

0

您應該使用該語言提供的排序過程。

try this tutorial.

基本上,你需要你的元類來實現java.lang.Comparable的,其中你只是委託給obj.name.compareTo(other.name)

那麼你可以使用Collections.sort(yourCollection)

或者你可以創建一個知道如何比較對象的java.util.Comparator

+3

Quote:「我正在用Java實現我自己的鏈表。」這是一個學習練習,不會通過使用罐裝API來實現。 – 2009-12-06 09:38:42

+0

這個問題並沒有說明這是一個學習練習,也不應該使用'canned'API。那是你的解釋。 – pstanton 2009-12-06 09:42:59

+1

我的解釋是,這也是一個學習練習。否則,他不需要實現鏈表。 – 2009-12-06 12:01:01

0

要獲得良好性能,您可以使用Merge Sort。 它的時間複雜度是O(n * log(n)),並且可以在沒有列表內存開銷的情況下實現。

泡沫排序不好的排序方法。你可以閱讀What is a bubble sort good for?瞭解詳情。

+0

是的,當然有更好的排序比泡泡排序,但我認爲運行時O(n^2)不是那麼糟糕小輸入我正在測試它(~50條目)。此外,排序是「就地」完成的,因此在進行「合併」過程時,我不必分配更多空間。也許以後我會實現一個快速排序算法,謝謝你的建議。 – Aaron 2009-12-06 17:13:36

+0

@Aaron如果你只有50個項目,泡泡排序是可以的,如果你更新問題,這將是一件好事。關於分配,我想請注意,爲了在_lists_上實現合併排序,不需要額外的分配。 (相比之下,在需要數組分配的情況下)。 – sergtk 2009-12-06 17:34:39

0

這可能有點太晚了。我將通過插入所有內容來開始構建列表,因爲對鏈表進行排序並不好玩。

我很積極,你的老師或教授不希望你使用java的本地庫。不過,據說,目前還沒有真正的快速方法來解決這個清單。

可能按照它們所在的順序讀取所有節點並將它們存儲到數組中。對陣列進行排序,然後重新鏈接節點。我認爲這個大哦的複雜性是O(n^2),所以實際上用鏈表進行冒泡排序就足夠了

+0

感謝您的想法。我在數據結構中做這個練習,所以我想避免使用額外的數組,並堅持僅僅列表本身。我首先嚐試在插入函數中整理一些東西,但是我發現在遍歷列表的同時更改列表很困難。例如,這就是我的迭代的樣子: Node temp = head; ! 而(TEMP = NULL; // 這裏做什麼 TEMP = temp.link; } 我能找到的地方插入節點的「索引」,但就應用更改到頭節點本身,我無法弄清楚:( – Aaron 2009-12-06 17:24:07

0

我已經完成了單鏈表上的合併排序,下面是代碼。

public class SortLinkedList { 

public static Node sortLinkedList(Node node) { 

    if (node == null || node.next == null) { 
     return node; 
    } 
    Node fast = node; 
    Node mid = node; 
    Node midPrev = node; 
    while (fast != null && fast.next != null) { 
     fast = fast.next.next; 
     midPrev = mid; 
     mid = mid.next; 
    } 
    midPrev.next = null; 
    Node node1 = sortLinkedList(node); 
    Node node2 = sortLinkedList(mid); 
    Node result = mergeTwoSortedLinkedLists(node1, node2); 
    return result; 
} 

public static Node mergeTwoSortedLinkedLists(Node node1, Node node2) { 
    if (null == node1 && node2 != null) { 
     return node2; 
    } else if (null == node2 && node1 != null) { 
     return node1; 
    } else if (null == node1 && null == node2) { 
     return null; 
    } else { 

     Node result = node1.data <= node2.data ? node1 : node2; 
     Node prev1 = null; 
     while (node1 != null && node2 != null) { 
      if (node1.data <= node2.data) { 
       prev1 = node1; 
       node1 = node1.next; 
      } else { 
       Node next2 = node2.next; 
       node2.next = node1; 
       if (prev1 != null) { 
        prev1.next = node2; 
       } 
       node1 = node2; 
       node2 = next2; 
      } 
     } 
     if (node1 == null && node2 != null) { 
      prev1.next = node2; 
     } 
     return result; 
    } 
} 

public static void traverseNode(Node node) { 
    while (node != null) { 
     System.out.print(node + " "); 
     node = node.next; 
    } 
    System.out.println(); 

} 

public static void main(String[] args) { 
    MyLinkedList ll1 = new MyLinkedList(); 

    ll1.insertAtEnd(10); 
    ll1.insertAtEnd(2); 
    ll1.insertAtEnd(20); 
    ll1.insertAtEnd(4); 
    ll1.insertAtEnd(9); 
    ll1.insertAtEnd(7); 
    ll1.insertAtEnd(15); 
    ll1.insertAtEnd(-3); 
    System.out.print("list: "); 
    ll1.traverse(); 
    System.out.println(); 
    traverseNode(sortLinkedList(ll1.start)); 

} 

}

Node類:

public class Node { 
int data; 
Node next; 

public Node() { 
    data = 0; 
    next = null; 
} 

public Node(int data) { 
    this.data = data; 
} 

public int getData() { 
    return this.data; 
} 

public Node getNext() { 
    return this.next; 
} 

public void setData(int data) { 
    this.data = data; 
} 

public void setNext(Node next) { 
    this.next = next; 
} 

@Override 
public String toString() { 
    return "[ " + data + " ]"; 
} 

}

的MyLinkedList類:

public class MyLinkedList { 
Node start; 

public void insertAtEnd(int data) { 
    Node newNode = new Node(data); 
    if (start == null) { 
     start = newNode; 
     return; 
    } 
    Node traverse = start; 
    while (traverse.getNext() != null) { 
     traverse = traverse.getNext(); 
    } 
    traverse.setNext(newNode); 
} 

public void traverse() { 
    if (start == null) 
     System.out.println("List is empty"); 
    else { 
     Node tempNode = start; 
     do { 
      System.out.print(tempNode.getData() + " "); 
      tempNode = tempNode.getNext(); 
     } while (tempNode != null); 
     System.out.println(); 
    } 
} 

}