[英]Merge sort on a linked list
因此,我一直在嘗試使用合並排序對鏈接列表進行排序,我找到了這段代碼並嘗試對其進行處理,但是它似乎沒有真正起作用嗎?
可能是什么問題? 我不太了解getMiddle方法,盡管我知道它應該獲取列表的中間值才能處理列表本身中的2個列表
這是代碼;
public Node mergeSort(Node head) {
if (head == null || head.link == null) {
return head;
}
Node middle = getMiddle(head);
Node sHalf = middle.link;
middle.link = null;
return merge(mergeSort(head), mergeSort(sHalf));
}
public Node merge(Node a, Node b) {
Node dummyHead;
Node current;
dummyHead = new Node();
current = dummyHead;
while (a != null && b != null) {
if ((int) a.getData() <= (int) b.getData()) {
current.link = a;
a.link = a;
}
else {
current.link = b;
b.link = a;
}
current = current.link;
}
current.link = (a == null) ? b : a;
return dummyHead;
}
public Node getMiddle(Node head) {
if (head == null) {
return head;
}
Node slow, fast;
slow = fast = head;
while (fast.link != null && fast.link.link != null) {
slow = slow.link;
fast = fast.link.link;
}
return slow;
}
在主要方法中:
Object data;
MyLinkedList list = new MyLinkedList(); //empty list.
for (int i = 0; i < 3; i++) { //filling the list
data = console.nextInt();
list.insertAtFront(data);
}
System.out.print("Print(1): ");
list.printList();
list.mergeSort(list.getHead());
System.out.print("List after sorting: ");
list.printList();
一個問題是getMiddle
方法不能正確返回中間Node
。
考慮一個具有5個節點(a,b,c,d,e)的鏈表
head
, slow
和fast
都從索引0(a)開始。
在while
循環的第一次迭代之后, slow
為1(b), fast
為2(c); 在第二次迭代之后, slow
為2(c),快速為4(e)。 它們都不都是null,所以又發生了一次迭代,將慢速設為3(d),將快速null
。 由於fast
為null,因此退出while
循環並返回slow
; 但是slow
是節點3(d),而不是中間節點2(c)。
獲取中間節點的另一種方法是僅使用節點數:
public Node getMiddle(Node head) {
Node counter = head;
int numNodes = 0;
while(counter != null) {
counter = counter.link;
numNodes++;
}
if(numNodes == 0)
return null;
Node middle = head;
for(int i=0; i<numNodes/2; i++)
middle = middle.link;
return middle;
}
我的mergeSort
方法很好,但是從技術上講,如果head.link
為null
,則只需要返回head
,而不是head
本身為null
(因為無論如何都不會發生):
public Node mergeSort(Node head) {
if (head.link == null) {
return head;
}
// same
}
最重要的是,您的merge
方法。 您可以在Node
類中編寫一個public void setData(Object)
方法,以使此操作更容易。 以下代碼應該可以工作,盡管我不能斷言這是完成這項工作的最好/最有效的方法
public Node merge(Node a, Node b) {
Node combined = new Node();
Node current = combined;
while(a != null || b != null) {
if(a == null)
addNode(current, b);
if(b == null)
addNode(current, a);
if((int)a.getData()<(int)b.getData())
addNode(current, a);
else
addNode(current, b);
}
return combined;
}
使用以下輔助方法:
public void addNode(Node n1, Node n2) {
n1.setData((int)n2.getData());
n1.link = new Node();
n1 = n1.link;
n2 = n2.link
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.