真的很快跳到双链表的中间

时间:2011-05-09 13:45:27

标签: java optimization linked-list

有没有办法真正快速地跳转到双向链接列表的中间元素而不是

for(int i = 0; i <= numOfElements/2; i++){
element = element.next;
}

在我的代码中需要这么多时间,如果我会对它进行优化,那真的很酷:)

6 个答案:

答案 0 :(得分:10)

链接(或双重链接)列表的要点是随机访问速度很慢(O(n))。

您需要使用其他类型的列表,例如skip list

答案 1 :(得分:5)

链表的重点是无法做到这一点。但是,存在(间接)允许该操作的其他数据结构。一个这样的数据结构是skip list,其名称来源于它可以精确地执行:跳过项目。

此数据结构不能直接应用于您的情况,因为跳过列表实现了词典,不允许直接访问索引项。但是,一般结构可以相应调整。

答案 2 :(得分:0)

我不确定这样做有多大意义取决于你需要一个双向链表的原因。理想情况下,您可以选择不使用它。但是如果不是这样的话,你可以用另一种类型的数据结构支持它,例如带有整数作为键的hashmap。那么你可以这样:

element.get(numOfElements/2);

答案 3 :(得分:0)

当你说“跳到中间”时,你的意思是每次都是确切的中间元素吗?或者只是“除了开头或结尾之外的某个地方,但确切的地方会有所不同”?

如果你的意思是确切的中间,你可以保持一个指向列表中间的指针以及通常的开始和结束指针。每次在列表中添加或删除条目时,都可能需要移动此指针。请注意,两侧需要两个插件才能将其移动一个位置,下方的一个插件和上方的一个插件将被取消。所以你必须保持一个“半柜台”。当下面插入一个项目时,从半个计数器中减去一个。在上面插入项目时,添加一个。如果半计数器现在为-2,则将中间指针向下移动一个插槽并将半计数器复位为0.如果半计数器现在为+2,则将中间指针向上移动一个插槽并复位半计数器。我曾在几年前这样做过。我忘记了原因。

如果你的意思不是确切的中间,那么我认为答案是“它无法完成”。我想,你可以在列表中保留一些指向各个点的指针。就像有一个带有第一个A,第一个B等标签的字典

或者我想如果你知道你经常需要“非常接近中间”,你可以保持一个中间指针,如上所述,然后从那里搜索。

这是否有助于解决您真正想要解决的问题,如果没有更多信息,我不能说。

答案 4 :(得分:0)

你可以保留一个中间指针,但每次更新列表时都需要调整,如果你只需要一个足够的近似值

或保留2个单独的列表,每次访问中间时都要调整它们,直到它们长度相等(保持长度作为每个的单独变量)

public class DoubledLickedList{
    private Node fhead,ftail,shead,stail;
    private AtomicInteger fsize,sSize;

    public Class Node{
        private Node next;
        private Node prev;
        public Node getNext(){
            if(next==null && next==ftail)return shead;
            return next;
        }

        public Node getPrev(){
            if(prev==null && prev==shead)return ftail;
            return prev;
        }
    }

    public Node getMiddle(){
        adjustToMiddle();
        return ftail;
    }

    private void adjustToMiddle(){
        while(fsize.get()>sSize.get()+1){
            //pop first and push it to the second
            fsize.incrementAndGet();
            sSize.decrementAndGet();
        }
        while(sSize.get()>fsize.get()+1){
            //pop second and push it to the first
            sSize.incrementAndGet();
            fsize.decrementAndGet();
        }
    }

 }

答案 5 :(得分:0)

如果您根本不需要列表,则可以使用ArrayTreeMapHashMap

所有人都可以更快地随机访问。