Java 排序链接列表而不重新链接节点
我已经知道如何对链表进行排序,但是我的方法与大多数同学有点不同。我没有重新链接节点,而是使用类似于mutator或setter的方法对元素进行排序,并将元素放置在适当的位置 以下是一个例子:Java 排序链接列表而不重新链接节点,java,sorting,linked-list,Java,Sorting,Linked List,我已经知道如何对链表进行排序,但是我的方法与大多数同学有点不同。我没有重新链接节点,而是使用类似于mutator或setter的方法对元素进行排序,并将元素放置在适当的位置 以下是一个例子: for(Node<E> x = head.next; x != null; x = x.next) { E temp = x.element; Node<E> y = x.previous; Node<E> p = y.next; for(
for(Node<E> x = head.next; x != null; x = x.next) {
E temp = x.element;
Node<E> y = x.previous;
Node<E> p = y.next;
for(; y != null && y.element.compareTo(temp) > 0; y = y.previous) {
p = y;
y.next.setElement(y.element);
}
p.setElement(temp);
}
这是正确的
现在我的问题是,如果我这样做而不是复杂的节点重新链接,我会作弊吗?这是对链接列表排序的错误做法吗?[emphasis added]
在计算机科学中,排序算法是将列表元素按一定顺序排列的算法
链表的元素是一个节点,由数据和指向列表中下一个节点的引用链接组成
在对链表进行排序的方式中,您只是将链表元素的数据部分移动/放置到其正确的位置,但引用部分仍然是引用相同的下一个节点。当您在排序后打印列表时,您将以排序的顺序获得输出,但实际上您只移动了列表的数据部分,而不是整个元素,我认为这不是对链接列表进行排序的适当方式
举个例子:
以ele作为类成员的双链表,该类包含int类型的数据,而previous和next是包含previous和next节点引用的成员。
节点类将如下所示:
class Node{
int ele;
Node previous;
Node next;
....
....
}
现在,您已经编写了在排序时将元素ele值放置到适当位置的代码
假设您需要向链接列表的节点添加更多信息:
class Node{
int element;
char char_ele; // newly added member
string str_ele; // newly added member
Node previous;
Node next;
....
....
}
现在有了这个更改,您必须在排序代码中进行更改,以便在排序时将char_ele和str_ele与ele一起放置在适当的位置。
但是,如果您实现了正确的链表排序,其中根据排序条件重新链接节点,则无需对实现进行任何更改,而不考虑节点数据部分的更改。您的方法没有任何欺骗。这完全取决于你需要什么。如果不需要交换引用,那么实现的方法更简单,不应该有任何其他问题
但是假设您的节点是一个更复杂的对象。从可读性的角度来看,复制内容可能不太好。或者,您的用例需要交换引用,那么最好重新排列节点以便于可读,并且只有在需要交换引用时才可以选择。事实上,这是面试问题的解决方案,在不更改任何下一个字段的情况下对链表进行排序。然而,这是一种欺骗,使用最简单的方法,因为它没有显示任何处理指针的能力。使用指针可以更改标题或下一个字段。只要节点不向公众公开(这无论如何都是个坏主意),您的版本就可以工作 通过获得指针的实际操作经验,您可以使未来的编程工作变得相当容易,因为这仍然很容易 信息: 你为我走在0。。N、 对于i+1中的j。。N的复杂度为ON²-二次方。3倍于元素,9倍于元素
对于阵列,可以使用更快的log N。我不认为这是一种不好的做法。Java本身也做了同样的事情,只是它更进一步,在数组中对列表之外的元素进行排序: 获取包含此列表中所有元素的数组,对数组进行排序,并在此列表上迭代,从数组中的相应位置重置每个元素 在OpenJDK中,未找到Oracle的联机:
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}