我已经知道这个问题的各种答案。但是我的代码中有一个非常令人困惑的错误。以下是一系列println()调用,以查看我创建的列表是否正确排序。
ListNode list_b = new ListNode(3, new ListNode(-2));
System.out.println("Checking the string conversion: " +
sut.convertToString(list_b)); //output is 3,-2, as expected. Expected result of sorting is -2,3.
System.out.println("Now checking the
string conversion of the sorted list: " +
sut.convertToString(sut.sort(list_b, int_comparator))); //output is -2,3 as expected.
System.out.println("Now this is list_b following the sorting,
by calling the element and next directly: "
+ list_b.element + "," + list_b.next); //3,null. How the hell did that happen!?!??!!?
convertToString方法如下:
public String convertToString(ListNode head) {
if (head != null) {
String representation = "";
if (!head.element.equals(null))
representation += head.element.toString();
ListNode next = null;
if (head.next != null)
next = head.next;
if (next != null && !next.element.equals(null))
representation += "," + next.element.toString();
while (next != null) {
if (next.next != null) {
next = next.next;
if (!next.element.equals(null))
representation += "," + next.element.toString();
}
else
break;
}
return representation;
}
else
return "";
}
实际的排序方法仍在进行中,虽然相当简单:
public ListNode sort(ListNode head, Comparator comparator) {
if (head != null) {
ListNode next = null;
if (head.next != null)
next = head.next;
else
return head;
if (comparator.compare(head.element, next.element) > 0) {
head.next = next.next;
next.next = head;
head = next;
}
return head;
}
return null;
}
有人愿意解释我是如何设法做出看似不可能的事吗?我怎么会发生这样的事情!非常感谢能够解释的任何人!
编辑:谢谢你的回答和建议。我应该澄清,然后在列表上执行以下测试:
assertTrue(sut.deepEquals(list_a, sut.sort(list_a, int_comparator)));
assertFalse(sut.deepEquals(list_b, sut.sort(list_b, int_comparator)));
assertTrue(sut.deepEquals(new ListNode(-2, new ListNode(3)), sut.sort(list_b, int_comparator)));
assertTrue(sut.deepEquals(new ListNode(-14, new ListNode(-2, new ListNode(3))), sut.sort(list_c, int_comparator)));
显然,这意味着list_b的任何更新(即list_b = sut.sort(list_b))都是不必要的。我要问的是你如何改变排序方法本身,以便不需要更新。
答案 0 :(得分:1)
非常简单:你在这段代码中对列表进行排序:
sut.convertToString(sut.sort(list_b, int_comparator)))
列表以这种方式转换:
3 -> -2 -> null ====> -2 -> 3 -> null
^ ^
| |
list_b list_b
sut.sort
返回列表的新前端(头部),它应该是新的list_b
,但由于您没有更新该值,因此它指向第二个节点列表,从而产生"3 , null"
答案 1 :(得分:1)
嗯......您正在更改sort
方法中传递节点的内部。变量list_b
仍然指的是节点“3”,即排序后不再有后继节点。
您的排序方法返回排序列表的新头。但是之后你不会使用它!
将您的代码段更改为:
list_b = sut.sort(list_b, int_comparator);
System.out.println(sut.convertToString(list_b));
答案 2 :(得分:0)
list_b
引用包含3的节点,并将节点2作为下一个元素。
然后您对列表进行排序。这会更改包含3的节点:它的下一个节点现在为null,因为它成为列表的最后一个元素。它还改变节点2,现在节点3作为下一个元素。但list_b仍然是对包含3的节点的引用。
当您打印节点list_b时,结果会得到3, null
。
编辑:
回答你的上一个问题:
如何更改排序方法本身,以便不必更新
您应该拥有一个实际的LinkedList类(与标准的java.util.LinkedList类完全相同)。你所拥有的课程并不代表一个清单。它表示节点链中的节点。
LinkedList类将具有对头节点的引用,并且将包含迭代存储在列表中的值,将其转换为String,对其进行排序等所需的所有方法。当然,对列表进行排序将暗示更改对LinkedList对象内的头节点的引用。但这对LinkedList类的用户来说是透明的,它永远不会直接操纵节点。
当然,如果你开始关注如何使用正确的LinkedList类,你应该只使用标准的,记录的和测试的标准类。