以Kotlin或Java的恒定时间复杂度O(1)的Concat链表

时间:2019-03-01 14:02:46

标签: java kotlin linked-list concatenation concat

我正在做的是串联动态生成的链表,一次仅2个。如何在Kotlin或Java中以恒定的时间复杂度O(1)做到这一点?

This similar question in Java告诉我java.util.LinkedList不支持固定时间添加。 Google Guava Iterators.concat只能在一个调用中组合2个或多个迭代器,这会导致多层包装并在我的情况下进行迭代时会增加复杂性。

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访问属性。