我有两个链表:
"a":1->2->3->空
"b":4->5->空
我想将它们合并为:1->4->2->5->3->空
我写了一个函数:
private void merge(ListNode a, ListNode b){
ListNode cur = new ListNode(0);
while(a != null && b != null){
cur.next = a;
cur = cur.next;
cur.next = b;
cur = cur.next;
b=b.next;
a=a.next;
}
if(a==null && b==null) return;
else if(a==null){
cur.next = b;
}else if(b==null){
cur.next = a;
}
return;
}
我想的是用一个"cur"来记录这两个链表"a"one_answers"b"中的每个节点。然后这两个链表"a"one_answers"b"移动到它的下一个节点。然后转到下一个WHILE循环。
然而,这是错误的。当我调试时,在第一个WHILE循环中,当它完成这个时
cur.next = b;
它表明变量将如下变化:
a: [1,5,4]
b: [5,4]
cur: [1,5,4]
我很困惑为什么"a"链表会变成[1,5,4]?我认为"a"链表在这一点上不会改变,它保持为[1,2,3]
--------但当我把WHILE循环改成这样时,它就起作用了:
while(a != null && b != null){
cur.next = a;
a=a.next;
cur = cur.next;
cur.next = b;
b=b.next;
cur = cur.next;
}
所以我的问题是:这两个WHILE循环有什么区别
while(a != null && b != null){
cur.next = a;
a=a.next;
cur = cur.next;
cur.next = b;
b=b.next;
cur = cur.next;
}
while(a != null && b != null){
cur.next = a;
cur = cur.next;
cur.next = b;
cur = cur.next;
b=b.next;
a=a.next;
}
当cur
指向仍需要next的节点时,仍然无法将其分配给next的问题。
方法末尾的提示return;
是不需要的。
这可能有助于首先使用递归,做一些简单的工作,并调用相同方法的其他实例来完成其余工作。
递归是:
private ListNode merge(ListNode a, ListNode b) {
if (a == null) {
return b;
} else if (b == null) {
return a;
}
ListNode anext = a.next;
a.next = merge(b, a.next);
return a;
}
它变得迭代:
private ListNode merge(ListNode a, ListNode b) {
while (true) {
if (a == null) {
return b;
} else if (b == null) {
return a;
}
ListNode anext = a.next;
a.next = b;
a = b;
b = anext;
}
}
这将处理具有不同长度的列表,因此需要一个结果。
难点在于,调用的参数没有采取两个步骤a.next和b.next。
您的版本将结果放入a
中,并要求两个列表的长度相同。CCD_ 4为空而CCD_。
在您的第一个版本中,首先引入了0元素。
是的,while循环中有一个错误。对于正确的合并算法,循环不变量应该在每次迭代的末尾,而循环ListNode
a和b应该指向其各自列表中的下一个元素。
while(a != null && b != null){
cur.next = a;
cur = cur.next;
cur.next = b;
cur = cur.next;
b=b.next;
a=a.next; // you are making a point to node in list b , which is wrong .
}
根据您的测试数据
列出a:1->2-3列表b:4->5
让我们在第一次迭代后检查while循环的不变量
(i(a=a.next
将a设置为b中的第一个节点,即4,同时它应该指向它自己的列表1->2->3
中的下一个元素,即2
这会破坏你的算法。