Quicksort三个中位数

时间:2013-06-11 21:04:44

标签: java sorting

我正在进行使用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();
    }
}

这使它适用于所有长度。

2 个答案:

答案 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
  1. 第一个node1和node2设置为“first。”。
  2. 然后node1变为a,node2变为b。
  3. 然后node1变为b,node2变为b.getNext()。getNext()或者换句话说Null.getNext。
  4. 该算法适用于奇数长度列表,因为node2.getNext()。getNext()将始终落在空值