簡體   English   中英

合並排序到鏈表上

[英]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)的鏈表

headslowfast都從索引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.linknull ,則只需要返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM