Java LinkedList一分为二(合并排序)
目前我正在学习使用链表合并排序。我不太明白如何将原始ListNode一分为二 我不明白为什么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
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个节点的列表。谢谢!这是有道理的!