我正在进行使用LinkedList排序的快速排序练习,(我知道它不高效,而且毫无意义,它适用于课程)。我理解Quick Sort方法的工作原理,以及三种策略的中位数。例如,我的代码只适用于某些长度。
这很好用:
7 6 5 4 3 2 1
,pivot = 4
7 6 5
,pivot = 6 | 3 2 1
,pivot = 2
现在,对于任何不那样的东西,即
5 4 3 2 1
,pivot = 3
5 4
,抛出错误| 2 1
会抛出错误。
以下是我的代码:
在LinkedList中查找中间节点。
public Node findMiddleNode() {
Node node1 = first;
Node node2 = first;
while(node2.getNext() != null && node2.getNext().getNext()!= null) {
node1 = node1.getNext();
node2 = node2.getNext().getNext();
}
return node1;
}
查找第一个,中间和最后一个节点的中位数。
public Node medianOfThree() {
Node firstNode = first;
Node lastNode = last;
Node middleNode = findMiddleNode();
if((firstNode.getData() - middleNode.getData()) * (lastNode.getData() - firstNode.getData()) >= 0) {
return firstNode;
} else if((middleNode.getData() - firstNode.getData()) * (lastNode.getData() - middleNode.getData()) >= 0) {
return middleNode;
} else {
return lastNode;
}
}
从列表中删除枢轴,这是破坏的方法。
private Node chooseAndRemovePivot() {
Node pivot = medianOfThree();
Node previous = first;
// If the pivot is the first Node.
if(previous == pivot) {
first = previous.getNext();
}
// Gets the last Node before the pivot
while(previous.getNext() != pivot) {
previous = previous.getNext();
}
previous.setNext(pivot.getNext());
pivot.setNext(null);
size--;
if (size == 0)
last = null;
return pivot;
}
任何人都可以指出这里出了什么问题,我确信这是我犯的一个简单错误。
编辑:解决方案;
在方法chooseAndRemovePivot();
中// If the pivot is the first Node.
if(previous == pivot) {
first = previous.getNext();
} else {
// Gets the last Node before the pivot
while(previous.getNext() != pivot) {
previous = previous.getNext();
}
}
这使它适用于所有长度。
答案 0 :(得分:2)
对于长度为2的列表,medianOfThree
函数将返回pivot == first
。因此,此代码:
// Gets the last Node before the pivot
while(previous.getNext() != pivot) {
previous = previous.getNext();
}
...永远不会找到终端条件,而是在到达列表末尾时指定previous = null
。然后下一次迭代将抛出NullPointerException
。
答案 1 :(得分:0)
我相信你的findMiddleNode()函数中存在错误。具体来说,node2.getNext.getNext()不会检查node2.getNext()是否为null
在具有偶数项的列表中,node2.getNext()。getNext()将在末尾运行。有效地将语句减少为Null.getNext(),这是一个错误。
例如使用列表
first -> a -> b -> null
该算法适用于奇数长度列表,因为node2.getNext()。getNext()将始终落在空值