簡體   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