Java LinkedList一分为二(合并排序)

Java LinkedList一分为二(合并排序),java,sorting,linked-list,mergesort,Java,Sorting,Linked List,Mergesort,目前我正在学习使用链表合并排序。我不太明白如何将原始ListNode一分为二 我不明白为什么listnodeleft=mergeSort(head)头不是整个原始ListNode的左半部分吗?为什么getMiddleNode方法只返回slowptr 我假设,listnodeleft=mergeSort(head)只包含左半边,但我想了解头部是如何变成左半边的 谢谢大家! 这是我的密码 class Solution { public ListNode mergeSort(ListNode he

目前我正在学习使用链表合并排序。我不太明白如何将原始ListNode一分为二

我不明白为什么
listnodeleft=mergeSort(head)头不是整个原始ListNode的左半部分吗?为什么getMiddleNode方法只返回slowptr

我假设,
listnodeleft=mergeSort(head)只包含左半边,但我想了解头部是如何变成左半边的

谢谢大家!

这是我的密码

class Solution {
  public ListNode mergeSort(ListNode head) {
    if(head == null || head.next == null){
      return head;
    }
    
    ListNode middle = getMiddleNode(head);
    
    ListNode left = mergeSort(head);
    ListNode right = mergeSort(middle);
    
    return merge(left, right);
  }
  
  ListNode getMiddleNode(ListNode head)
  {
    ListNode pre = null;
    ListNode slowptr = head;
    ListNode fastptr = head;
    
    while(fastptr != null || fastptr.next != null)
    {
      pre = slowptr;
      slowptr = slowptr.next;
      fastptr = fastptr.next.next;
    }
    
    pre.next = null;
    return slowptr;
  }
}
我不清楚为什么ListNode left=mergeSort(head);不是吗 头整个原来的ListNode不只有左半边

带有
pre.next=null中间节点之前节点的下一个节点设置为null,因此linkedList的前半部分(从head到pre,inklusiv)和后半部分(从中间到end,inklusiv)之间不存在链接,因此它们已成为两个独立的列表

为什么getMiddleNode方法只返回slowptr


因为在循环之后,LoVPTR指向链接列表中间的节点。slowptr和fastptr初始化为head,然后在列表中“漫游”。但是FASTPTR的速度是LoSpTR的两倍(<代码> FASPTR = FASPTR。下一步;而不是<代码>慢pTrp=慢波。下一步;),因此当FASPTPR在结尾时,LoVPTR已经在中间做了一半。

< P>您可以清楚地理解为什么<强> ListNodoLe=合并ESESORT(头);is仅包含列表的左侧部分,方法是在getMiddleNode(head)之后的右侧打印head

原因是在getMiddleNode(head)函数中将列表分成两半。当您通过递归一次又一次地做同样的事情时,连续地,您将得到列表的左半部分,其边界是当前中间,而右半部分正好相反(即,列表的右半部分,其边界是当前中间到当前最后一个元素)

例如,考虑这一个是您要应用合并排序的初始列表。 11->8->3->35->4

在getMiddleNode(head)之后,您将得到如下两个列表:

11->8->3(左)和35->4(右)

现在,如果我们再次调用相同的函数,我们将得到:

11->8(左)和3(右)[用于上一个左部件]

35和4(适用于前右部分)[适用于前右部分]

现在,对于找到的上一个右部件基本情况,我们可以对其进行排序/交换, 同样,上一个左半部分的右侧也是如此,即3

到目前为止,我们的名单是:3,4,35

如果我们在上一个左部分(11->8)的左边应用相同的逻辑,我们将得到:

11(左)和8(右)

现在又为当前列表找到了基本情况,所以我们可以对它们进行排序,最后我们将得到

3481135


这就是传说中的合并排序的工作原理。

请注意,a避免了扫描列表以拆分列表。而是使用一个小的(25到32)节点引用数组,其中数组[i]要么为空,要么指向2^i个节点的列表。谢谢!这是有道理的!