简体   繁体   English

算法:合并排序与链表缺少的项目

[英]Algorithm: Merge Sort with linked list missing items

I am trying to sort my linked list with merge sort. 我正在尝试使用合并排序对链接列表进行排序。 The list is actually sorted but it is kind of missing first item(s). 该列表实际上已排序,但是有点缺少第一项。

Merge sort functions: 合并排序功能:

public Node mergeSort(Node head) {
    if (head == null || head.next == null) {
        return head;
    }

    Node middle = middleElement(head);
    Node nextofMiddle = middle.next;
    middle.next = null;
    return merge(mergeSort(head), mergeSort(nextofMiddle));
}

public Node merge(Node left, Node right) {

    Node temp = new Node();
    Node newHead = temp;
    while (left != null && right != null) {
        if (left.info <= right.info) {
            temp.next = left;
            temp = left;
            left = temp.next;
        } else {
            temp.next = right;
            temp = right;
            right = temp.next;
        }
    }
    temp.next = (left == null) ? right : left;
    return newHead;
}

public Node middleElement(Node head) {
    if (head == null) {
        return head;
    }
    Node slow = head;
    Node fast = head;
    while (fast.next != null && fast.next.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow;
}

So I printed the list to the screen using traverse: 所以我使用遍历将列表打印到屏幕上:

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

    mll.insert(3);
    mll.insert(5);
    mll.insert(9);
    mll.insert(1);
    mll.insert(8);
    mll.insert(7);
    mll.insert(2);



    mll.mergeSort(mll.head);
    mll.traverse();

}

I have result like this: 1 and 2 missing! 我得到这样的结果: 1和2丢失了!

After checking, i noticed that the "tail" of the linked list value is still 2. I don't know why can someone help?. 经过检查后,我注意到链接列表值的“尾部”仍然为2。我不知道为什么有人可以帮助您。 I'm really new to programming so sorry for any inconvenience. 我真的是编程新手,对于给您带来的不便深表歉意。 Thank you for reading! 感谢您的阅读!

You have a couple problems that I can see. 您有几个问题,我可以看到。 One, mentioned by @rcgldr, in the comments is that you merge method is returning the temp node newHead , but that node was no value and is not part of your graph. @rcgldr在注释中提到的一个是,您的merge方法将返回临时节点newHead ,但是该节点没有值,也不属于图形。 You need to return it's child newHead.next . 您需要返回它的子级newHead.next

The other problem is that you never reset the head of your list. 另一个问题是您永远不会重置列表的开头。 So after all the sorting, the head of mll still points to the original head, which in this case is 3 . 因此,在所有排序之后, mll的头仍指向原始头,在这种情况下为3 So when you traverse the list you skip 1 and 2 . 因此,当遍历列表时,将跳过12 I'm not sure what your linked list class looks like but something like this should be close -- just assign the final node returned by mergeSort to the head of the list. 我不确定您的链表类是什么样子,但是类似这样的东西应该很接近-只需将mergeSort返回的最终节点分配给列表的头即可。 Then when you traverse you should be starting in the right spot: 然后,当您遍历时,您应该在正确的位置开始:

    mll.head = mll.mergeSort(mll.head);
    mll.traverse();

You're not far from a correct solution. 您距离正确的解决方案不远。 I was able to get a working sort by adding 1 line and changing 3. 我能够通过添加1行并更改3来获得有效的排序。

Your merge isn't doing what you think it is. 您的合并没有按照您的想法进行。

Allocating a false head node (what you call temp , not a good choice of name; try falseHead ) is a fine idea. 分配一个错误的头节点(您称temp ,不是一个好的名称选择;请尝试falseHead )是一个好主意。 Then falseHead.next is the true head. 那么falseHead.next是真实的头部。 That's what you'll finally return as the sorted list. 这就是您最终将返回的排序列表。 Note that initially it's null , which is what you'd expect. 请注意,最初它为null ,这就是您所期望的。

What you're missing is a variable tail to reference the current last node in the merged list. 您缺少的是一个可变的tail以引用合并列表中的当前最后一个节点。 Since there is initially no last node at all, this should be initialized equal to falseHead . 由于最初根本没有最后一个节点,因此应将其初始化为falseHead Consequently, when you append the first element to the tail of the current result by setting tail.next , you'll also be setting falseHead.next , ie creating the head element. 因此,当你追加到第一个元素tail通过设置电流结果tail.next ,你也可以设置falseHead.next ,即创建头元素。 It all works out. 一切顺利。

Now, what is the logic for, say, removing the current head of the right list and appending it to the merge result? 现在,删除right列表的当前标题并将其附加到合并结果的逻辑是什么? It's just 3 steps: 只需3个步骤:

  1. Do the append operation by making tail.next the current head of right . 难道通过使追加操作tail.next现任掌门right
  2. Update tail to tail.next . tail更新为tail.next
  3. Remove the head of right by updating right to right.next . 取出的头部right通过更新right ,以right.next

Of course the left side is similar. 当然,左侧是相似的。

Good luck. 祝好运。 You're close. 你近了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM