在 Kotlin 或 Java 中以恒定时间复杂度 O(1) 连接列表
Concat linked lists in constant time complexity O(1) in Kotlin or Java
我正在做的是连接动态生成的链表,一次只有 2 个。如何在 Kotlin 或 Java?
中以恒定时间复杂度 O(1) 执行此操作
This similar question in Java tells me that java.util.LinkedList
doesn't support adding in constant time. And the Google Guava Iterators.concat
只能在一次调用中组合 2 个或更多迭代器,这会导致多层包装并在我的案例中增加迭代时的复杂性。
在 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)
}
}
这个函数 returns 一个 T
类型的 Iterator
延迟消耗 a
然后 b
最后 c
解决方案是这样的:
fun <T> combine(vararg iterators: Iterator<T>): Iterator<T> {
return iterator {
iterators.forEach { yieldAll(it) }
}
}
此实现采用 n
个迭代器并将它们合并为一个。
我在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 用于访问属性。
我正在做的是连接动态生成的链表,一次只有 2 个。如何在 Kotlin 或 Java?
中以恒定时间复杂度 O(1) 执行此操作This similar question in Java tells me that java.util.LinkedList
doesn't support adding in constant time. And the Google Guava Iterators.concat
只能在一次调用中组合 2 个或更多迭代器,这会导致多层包装并在我的案例中增加迭代时的复杂性。
在 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)
}
}
这个函数 returns 一个 T
类型的 Iterator
延迟消耗 a
然后 b
最后 c
解决方案是这样的:
fun <T> combine(vararg iterators: Iterator<T>): Iterator<T> {
return iterator {
iterators.forEach { yieldAll(it) }
}
}
此实现采用 n
个迭代器并将它们合并为一个。
我在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 用于访问属性。