链接列表getValue(int n)应为O(n / 2)

时间:2014-03-28 06:07:02

标签: java performance algorithm doubly-linked-list

标准的链接列表实现是双重链接的。因此我们分别有一个headNode和一个tailNode。我已经读过getValue(int n),作为返回第n个元素列表中保存的数据部分。现在假设我们在从headNode开始的Linked List上进行顺序搜索,如果该位置是列表中的最后一个元素,则最坏的情况是O(n)。但是,如果我们检查是否n> size / 2然后我们知道是否在headNode或tailNode开始遍历。这意味着它将执行O(n / 2),可以重写为O(1 / 2n)。

根据Big O Notation系数的规则无关紧要,因此最坏的情况仍然是O(n)。我在这个逻辑中看到了一个缺陷,因为如果我们有一个包含大量节点的列表,比如100万,那么最坏情况下500,000比1000万的最坏情况要好得多。最坏的情况是如果我们正在搜索的位置实际上是大小/ 2.我已经实现了这个代码并且发现当通过的位置小于size / 2时它们以相同的速度执行,但是,当传递的位置大于size / 2,它表现得更快。我的问题是,当这样一个简单的解决方案将最坏的情况减少一半时,我们怎么能说这是O(n)。显然系数很重要,我看不出我们如何得出它们无关的结论。这是代码:

//This is headed by firstNode and tailed by lastNode
public Node getValue(int position)
{
    if (!isEmpty() && position <= size)
    {

        if (position > (size / 2))
            return traverseReverse(position);
        else
            return sequentialSearch(position);

    }

    return null;
}

private Node traverseReverse(int searchIndex)
{
    Node currentNode = lastNode;
    int position = size;
    while (currentNode != null)
    {
        if (position == searchIndex)
            return currentNode;

        position--;
        currentNode = currentNode.previous;
    }

    return null;
}

private Node sequentialSearch(int position)
{
    Node currentNode = firstNode;
    int n = 0;

    while (currentNode != null)
    {
        if (n == position)
            return currentNode;

        n++;
        currentNode = currentNode.next;
    }

    return null;
}

1 个答案:

答案 0 :(得分:3)

复杂性和运行时是相关概念,但不完全相同。复杂性显示n与运行时之间的关系,n增加。

无论系数如何,线性关系都是O(n)。如果要比较最坏情况运行时,请务必这样做,但复杂性分析不是正确的工具。这只是一个起点。

无论您是从正面还是背面搜索链接列表,您需要查看的平均项目数量与其大小成正比。