我正在做的是串联动态生成的链表,一次仅2个。如何在Kotlin或Java中以恒定的时间复杂度O(1)做到这一点?
This similar question in Java告诉我java.util.LinkedList
不支持固定时间添加。 Google Guava Iterators.concat
只能在一个调用中组合2个或多个迭代器,这会导致多层包装并在我的情况下进行迭代时会增加复杂性。
答案 0 :(得分:3)
在Kotlin中,您可以使用Iterator
函数将多个iterator {...}
组合在一起,如下所示:
fun <T> combine(a: Iterator<T>, b: Iterator<T>, c: Iterator<T>): Iterator<T> {
return iterator {
yieldAll(a)
yieldAll(b)
yieldAll(c)
}
}
此函数返回类型为Iterator
的{{1}},它先后消耗T
然后消耗a
,最后消耗b
解决方案如下:
c
此实现采用fun <T> combine(vararg iterators: Iterator<T>): Iterator<T> {
return iterator {
iterators.forEach { yieldAll(it) }
}
}
个迭代器,并将它们组合为一个。
答案 1 :(得分:0)
我已经基于Java LinkedList
实现了单链接列表的简单版本,只是为了支持此concat函数。为简单起见,它仅实现Iterable
而不是List
:
Java实现:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class SimpleLinkedList<E> implements Iterable<E> {
Node<E> first;
Node<E> last;
static class Node<E> {
E item;
Node<E> next;
Node(E item, Node<E> next) {
this.item = item;
this.next = next;
}
}
static class NodeIterator<E> implements Iterator<E> {
private Node<E> node;
NodeIterator(Node<E> node) {
this.node = node;
}
public boolean hasNext() {
return node != null;
}
public E next() {
Node<E> currentNode = node;
if (currentNode == null) throw new NoSuchElementException();
node = currentNode.next;
return currentNode.item;
}
}
public Iterator<E> iterator() {
return new NodeIterator<>(first);
}
public void add(E element) {
// Copied from java.util.LinkedList
Node l = last;
Node<E> newNode = new Node<>(element, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
}
public void concatWith(SimpleLinkedList other) {
if (last != null) last.next = other.first;
else first = other.first;
if (other.last != null) last = other.last;
}
}
Kotlin的实现:
class SimpleLinkedList<E> : Iterable<E> {
var first: Node<E>? = null
var last: Node<E>? = null
class Node<E>(var item: E, var next: Node<E>? = null)
class NodeIterator<E>(var node: Node<E>?) : Iterator<E> {
override fun hasNext(): Boolean = node != null
override fun next(): E {
val currentNode = node
if (currentNode === null) throw NoSuchElementException()
node = currentNode.next
return currentNode.item
}
}
override fun iterator(): Iterator<E> = NodeIterator(first)
fun add(element: E) {
// Copied from java.util.LinkedList
val l = last
val newNode = Node(element, null)
last = newNode
if (l == null)
first = newNode
else
l.next = newNode
}
infix fun concatWith(other: SimpleLinkedList<E>) {
last.run {
if (this !== null) next = other.first
else first = other.first
}
other.last?.let { last = it }
}
}
Kotlin实现实际上比Java实现慢一点,因为使用getter和setter访问属性。