Java 树集合中有序操作的时间复杂度是多少?

Java 树集合中有序操作的时间复杂度是多少?,java,algorithm,complexity-theory,treeset,Java,Algorithm,Complexity Theory,Treeset,以下操作的时间复杂度是多少 first() last() lower() higher() 我假设这些时间是恒定的,但API不作任何保证。API不作任何保证,因为它们基于trie的标准模型。最佳情况为O(1),平均情况为O(logn),最坏情况为O(n) 从文件中: 此实现为基本操作(添加、删除和包含)提供了有保证的日志(n)时间开销 这些不是您要求的函数,但请考虑Java将如何遍历树集。实际上,对于一般实现,我认为这些操作都将是O(logN) 对于要成为O(1)的first()和last

以下操作的时间复杂度是多少

  • first()
  • last()
  • lower()
  • higher()

我假设这些时间是恒定的,但API不作任何保证。

API不作任何保证,因为它们基于trie的标准模型。最佳情况为O(1),平均情况为O(logn),最坏情况为O(n)

从文件中:

此实现为基本操作(添加、删除和包含)提供了有保证的日志(n)时间开销


这些不是您要求的函数,但请考虑Java将如何遍历树集。

实际上,对于一般实现,我认为这些操作都将是
O(logN)

  • 对于要成为
    O(1)
    first()
    last()
    ,树集实现需要分别维护指向树中最左侧和最右侧叶节点的指针。维护这些会为每次插入增加固定成本,至少为每次删除增加固定成本。实际上,实现可能会动态地找到最左/最右的节点。。。这是一个
    O(logN)
    操作

  • lower()
    higher()
    方法必须做与
    get
    相同的工作,因此是
    O(logN)


当然,您可以自己检查源代码,看看实际发生了什么。(正如其他人所做的:见下文。)

这将取决于实现。我对JAVA不太熟悉,但似乎所有这些操作都是遍历操作(获取最低元素、获取最高元素、获取下一个更高或下一个更低)

如果树被实现为一个like-an或任何其他类型的平衡树结构,那么您将看到每个操作的平均情况和最坏情况O(logn)时间,以及O(1)的最佳情况。

看起来first()和last()都将是O(logn)而不是O(1)(sun jdk 1.6.023)默认情况下由TreeSet使用的TreeMap的:

 /**
 * Returns the first Entry in the TreeMap (according to the TreeMap's
 * key-sort function).  Returns null if the TreeMap is empty.
 */
final Entry<K,V> getFirstEntry() {
    Entry<K,V> p = root;
    if (p != null)
        while (p.left != null)
            p = p.left;
    return p;
}

/**
 * Returns the last Entry in the TreeMap (according to the TreeMap's
 * key-sort function).  Returns null if the TreeMap is empty.
 */
final Entry<K,V> getLastEntry() {
    Entry<K,V> p = root;
    if (p != null)
        while (p.right != null)
            p = p.right;
    return p;
}
/**
*返回树映射中的第一个条目(根据树映射的
*键排序功能)。如果树映射为空,则返回null。
*/
最终条目getFirstEntry(){
条目p=根;
如果(p!=null)
while(p.left!=null)
p=p.左;
返回p;
}
/**
*返回树映射中的最后一个条目(根据树映射的
*键排序功能)。如果树映射为空,则返回null。
*/
最终条目getLastEntry(){
条目p=根;
如果(p!=null)
while(p.right!=null)
p=p.右;
返回p;
}

我实际上查找了源代码, 在中,first()调用maps.firstKey() 然后在

在firstNode()中,它执行while循环,一直向左

952: final Node<K, V> firstNode()
953: (
954: // Exploit fact that nil.left == nil.
955: Node node = root;
956: while (node.left != nil)
957: node = node.left;
958: return node;
959: )
952:最终节点firstNode()
953: (
954://利用nil.left==nil这一事实。
955:节点=根;
956:while(node.left!=nil)
957:node=node.left;
958:返回节点;
959: )

我看过源代码,但它太抽象了。我不确定第一个和最后一个是在哪里实施的。必须再看一些。树集是用树映射在内部实现的,因此大部分逻辑都在
树映射中。获取[First | Last | Lower | Higher]Entry()
。All遍历树以查找节点,因此Stephen C是正确的,O(log N)。但实现被指定为红黑树,因此它不依赖于实现。哈哈,yeh,现在已修复;)
952: final Node<K, V> firstNode()
953: (
954: // Exploit fact that nil.left == nil.
955: Node node = root;
956: while (node.left != nil)
957: node = node.left;
958: return node;
959: )