我希望能够在O(1)时间内访问我的双向链接列表中的某个节点。我知道,如果我遍历列表找到某个节点,它将需要O(n)时间,所以我想将节点映射到一个数组列表,在那里我可以在O(1)时间内访问节点。
我真的不确定如何进行此映射。我想看一个如何做到这一点的例子。
编辑: 我希望能够访问链表中的任何节点,这样我就可以在O(1)时间内移动节点。
示例:在O(1)时间内将ID为5的节点移动到列表的末尾。
编辑2:我上传了一张我想要完成的图片示例
答案 0 :(得分:0)
我不完全确定你的目的,你只想在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 );
================================
Re:你的编辑
你不能(或者没有我所知道的)。你本质上要求两全其美(链表和数组)。
答案 1 :(得分:0)
使用toArray()
方法将LinkedList转换为数组以进行恒定时间检索:
答案 2 :(得分:0)
LinkedHashMap:提供O(1)时间,键是双重链接列表。
答案 3 :(得分:0)
您无法使用内置数据结构ArrayList和LinkedList执行此操作。
一般来说,完全不可能同时拥有
可能性:
即使您尝试将链接列表与数组合并,也可以使用O(n)来删除/添加(因为您仍需要更新数组)。
好的,通过添加图片来显示您想要的内容,这是可行的。实际上,您正在重新实现LinkedHashMap之类的东西,但只能使用连续的整数键并能够操作“链接”部分。
如果您的链接列表包含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);