试图对链表进行排序

时间:2015-10-19 11:33:45

标签: java debugging linked-list

我已经知道这个问题的各种答案。但是我的代码中有一个非常令人困惑的错误。以下是一系列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))都是不必要的。我要问的是你如何改变排序方法本身,以便不需要更新。

3 个答案:

答案 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类,你应该只使用标准的,记录的和测试的标准类。