繁体   English   中英

Arraylist映射到链表节点

[英]Arraylist mapping to linkedlist nodes

我希望能够在O(1)时间访问我的双向链接列表中的某个节点。 我知道,如果我遍历列表以查找某个节点将花费O(n)的时间,所以我想将这些节点映射到一个数组列表,在这里我可以在O(1)的时间内访问这些节点。

我真的不确定如何进行此映射。 我想看一个如何做到这一点的例子。

编辑:我希望能够访问链表中的任何节点,因此我可以在O(1)时间内移动这些节点。

示例:将ID 5的节点在O(1)时间内移到列表末尾。

编辑2:我上传了我要完成的图片示例

在此处输入图片说明

我不确定您的用途,您是否只是想在O(1)中检索对象的索引?

它是这样的:

LinkedList<Object> aList; // your LinkedList
Map<Object, Integer> mapper = new HashMap<Object, Integer>();
Object[] arr = aList.toArray();
for( int i = 0; i < arr.length; i++ ){
    mapper.put( arr[i], i );
}

现在,如果您想在列表中找到一个对象,您要做的就是从mapper对象获取其索引

mapper.get( o );

================================

回复:您的编辑

您不能(或我所知道的没有)。 本质上,您要求两全其美(链接列表和数组)。

使用toArray()方法将LinkedList转换为数组以进行恒定时间检索:

LinkedList.toArray(arr)

LinkedHashMap :提供O(1)时间,并且密钥是双链表的有序顺序。

您无法使用内置数据结构ArrayList和LinkedList来执行此操作。

通常,根本不可能同时拥有

  • O(1)索引(按列表中的位置)
  • O(1)删除/添加/移动列表中的任何位置。

可能性:

  • 如果使用基于树的结构,则可以同时使用O(log(N))。
  • 您可以使用基于数组的结构访问O(1)进行索引,但是在中间进行删除/添加操作会得到O(n)。
  • 您可以在H(1)中添加/删除使用类似Hash-Map的结构,但它仅允许通过键访问O(1),而不允许通过索引访问(除了迭代,即O(n))。 (这意味着,如果您在中间添加/删除某些内容,则其后的索引不会更改。)

即使您尝试将链接列表与数组组合在一起,也要使用O(n)进行删除/添加操作(因为您仍然必须更新数组)。


好的,添加的图像可以显示您想要的图像,它是可行的。 实际上,您实际上是在重新实现LinkedHashMap之类的东西,但是只能使用连续的整数键并且可以操纵“ Linked”部分。

如果链接列表由Node对象组成,则将具有ArrayList<Node>

仅在将新节点添加到链表时才将元素添加到ArrayList,否则仅将ArrayList用于查找。

这是一个例子:

class FastIndexLinkedIntList<X> {
   class Node {
      Node next;
      Node prev;
      int key;
      X value;
      Node(int key, X val) { this.key = key; this.value = val; }
   }

   ArrayList<Node> indexedNodes = new ArrayList<Node>();
   Node head;
   Node tail;


   public void add(X value) {
      int key = indexedNodes.size();
      Node node = new Node(key, value);
      insertAtEnd(node);
      indexedNodes.add(node);
   }

   private void insertAtEnd(Node n) {
      if(tail == null) {
         assert head == null;
         head = n;
         tail = n;
         return;
      }
      n.prev = tail;
      n.next = null;
      tail.next = n;
      tail = n;
   }

   private void removeNode(Node n) {
      if(n.next == null) {
         assert n == tail;  // last node

         tail = n.prev;
         tail.next = null;
      }
      else {
         n.next.prev = n.prev;
      }

      if(n.prev == null) {
         assert n == head; // first node

         head = n.next;
         head.prev = null;
      }
      else {
         n.prev.next = n.next;
      }
   }

   public void moveNodeToEnd(int key) {
      Node n = indexedNodes.get(key);
      removeNode(n);
      insertAtEnd(n);
   }

}

您可能想在此处添加更多操作,但是对于问题中的示例而言,这些操作就足够了:

FastIndexedLinkedList<String> ll = new FastIndexedLinkedList<String>();
ll.add("0");
ll.add("1");
ll.add("2");
ll.add("3");
ll.moveNodeToEnd(2);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM