在PHP中高效插入和/或删除双向链表的元素

时间:2019-03-08 09:01:38

标签: php data-structures big-o doubly-linked-list

我需要使用双向链表数据结构,该结构允许我在恒定时间(O(1))的任何位置任意插入和/或删除元素,而无需重新索引任何内部数据结构。

我当时正在考虑实现自己的数据结构,但后来遇到SplDoublyLinkedListhttp://php.net/manual/en/class.spldoublylinkedlist.php)。

立即,有两件事使我感到怀疑:

  1. 它的SplDoublyLinkedList::add ( mixed $index , mixed $newval )方法采用一个$index参数,据说它是shuffles the previous value at that index (and all subsequent values) up through the list
  2. 它的删除对等方法SplDoublyLinkedList::offsetUnset还将索引作为参数并重新索引双向链表的内部数组。

这两点让我认为PHP中的SplDoublyLinkedList的行为更像Java ArrayList,在Java $dlist = new SplDoublyLinkedList(); $dlist->push('A'); $dlist->push('B'); $dlist->push('C'); var_dump($dlist); $dlist->add(1, 'Z'); echo "After insertion in the middle of the list:"; var_dump($dlist); 中,每次插入/删除操作后,数据结构的内部数组都会一次又一次地重新索引。 / p>

实际上,如果您运行以下代码,您将看到有一个内部数组被重新索引:

class SplDoublyLinkedList#1 (2) {
  private $flags =>
  int(0)
  private $dllist =>
  array(3) {
    [0] =>
    string(1) "A"
    [1] =>
    string(1) "B"
    [2] =>
    string(1) "C"
  }
}

After insertion in the middle of the list:

class SplDoublyLinkedList#1 (2) {
  private $flags =>
  int(0)
  private $dllist =>
  array(4) {
    [0] =>
    string(1) "A"
    [1] =>
    string(1) "Z"
    [2] =>
    string(1) "B"
    [3] =>
    string(1) "C"
  }
}

输出:

SplDoublyLinkedList::offsetUnset

O(1)也一样。

在双向链表中,没有索引的概念,只有具有上一个元素和下一个元素的节点允许SplDoublyLinkedList插入和删除(取自http://www.java2novice.com/data-structures-in-java/linked-list/doubly-linked-list/)。

插入: enter image description here

删除: enter image description here

您对PHP SplDoublyLinkedList::add的实现细节有何想法? SplDoublyLinkedList::offsetUnsetO(1)确实允许TypeElement element; getSuperElement(element.asType()); private void getSuperElement(TypeMirror mirror) { if (mirror == null ) return; List<? extends TypeMirror> mirrors = mTypeUtils.directSupertypes(mirror); if (mirrors == null || mirrors.isEmpty()) return; for (TypeMirror it : mirrors) { if (it.getKind() == TypeKind.DECLARED) { // this element is super class's element, you can do anything in here Element element = ((DeclaredType) it).asElement(); } getSuperElement(methodBuilder, componentName, it); } } 恒定时间进行插入/删除,还是我需要警惕,因为在内部它使用的数组在每次插入/删除操作之后都会重新索引?

感谢您的关注。

0 个答案:

没有答案