合并链表上的排序



所以我一直在尝试使用合并排序对链表进行排序,我找到了这段代码并尝试对其进行处理,但它并没有真正起作用?

它可能有什么问题?我不太确定 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)处快速。这些都不是空的,所以会发生另一个迭代,在 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如果head.linknull,而不是如果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
}

相关内容

  • 没有找到相关文章

最新更新