php SPL(Standard PHP Library) 主要用到的数据结构有:双向链表(SplDoublyLinkedList),栈(SplStack),队列(SplQueue),堆(SplHeap),大根堆(SplMaxHeap),小根堆(SplMinHeap), 优先级队列(SplPriorityQueue),固定数组(SplFixedArray),对象存储(SplStorageObject)。
双向链表(SplDoublyLinkedList)
数据类型:(c代码参考PHP7.0.0)
typedef struct _spl_ptr_llist_element {
struct _spl_ptr_llist_element *prev;
struct _spl_ptr_llist_element *next;
int rc; // 引用次数
void *data; // 数据类型
} spl_ptr_llist_element;
typedef struct _spl_ptr_llist {
spl_ptr_llist_element *head;
spl_ptr_llist_element *tail;
spl_ptr_llist_dtor_func dtor; // 删除元素 引用-1
spl_ptr_llist_ctor_func ctor; // 创建元素 引用+1
int count; // 元素个数
} spl_ptr_llist;
struct _spl_dllist_object {
zend_object std;
spl_ptr_llist *llist;
int traverse_position;
spl_ptr_llist_element *traverse_pointer;
zval *retval;
int flags;
zend_function *fptr_offset_get;
zend_function *fptr_offset_set;
zend_function *fptr_offset_has;
zend_function *fptr_offset_del;
zend_function *fptr_count;
zend_class_entry *ce_get_iterator;
HashTable *debug_info;
};
class SplDoublyLinkedList implements Iterator , ArrayAccess , Countable { /* 方法 */
public __construct ( void )
public void add ( mixed $index , mixed $newval )
public mixed bottom ( void )
public int count ( void )
public mixed current ( void )
public int getIteratorMode ( void )
public bool isEmpty ( void )
public mixed key ( void )
public void next ( void )
public bool offsetExists ( mixed $index )
public mixed offsetGet ( mixed $index )
public void offsetSet ( mixed $index , mixed $newval )
public void offsetUnset ( mixed $index )
public mixed pop ( void )
public void prev ( void )
public void push ( mixed $value )
public void rewind ( void )
public string serialize ( void )
public void setIteratorMode ( int $mode )
public mixed shift ( void ) // 删除第一个元素
public mixed top ( void )
public void unserialize ( string $serialized )
public void unshift ( mixed $value ) //将value插入的第一个元素,原来的第一个元素不删除
public bool valid ( void )
}
需要注意的是:
add 是5.5+版本添加的函数,其它都是5.3+
从数据结构中可以看出,虽然许多函数中都包含有直接索引第index 个元素,如果不在范围则抛出OutOfRangeException异常,实际实现时时间复杂度为O(n)。
具体函数详细可参考php官方手册
栈(SplStack)
栈继承自SqlDoublyLinkedList,多了一个设置迭代模式的函数
void setIteratorMode ( int $mode );
其中默认为SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP
队列(SplQueue)
mixed dequeue ( void ) 从队列头部删除一个元素 === SplDoublyLinkedList::shift()void enqueue ( mixed $value ) 添加一个元素到队列=== SplDoublyLinkedList::push(mixed $value)
堆(SplHeap)
数据类型:栈继承自SqlDoublyLinkedList,多了的函数为
void setIteratorMode ( int $mode )
其中默认为 SplDoublyLinkedList::IT_MODE_LIFO | SplDoublyLinkedList::IT_MODE_KEEP
typedef struct _spl_ptr_heap {
zval *elements;
spl_ptr_heap_ctor_func ctor;
spl_ptr_heap_dtor_func dtor;
spl_ptr_heap_cmp_func cmp;
int count;
int max_size;
int flags;
} spl_ptr_heap;
typedef struct _spl_heap_object spl_heap_object;
typedef struct _spl_heap_it spl_heap_it;
struct _spl_heap_object {
spl_ptr_heap *heap;
int flags;
zend_class_entry *ce_get_iterator;
zend_function *fptr_cmp;
zend_function *fptr_count;
zend_object std;
};
static void spl_ptr_heap_insert(spl_ptr_heap *heap, zval *elem, void *cmp_userdata) { /* {{{ */
int i;
if (heap->count+1 > heap->max_size) {
/* we need to allocate more memory */
heap->elements = erealloc(heap->elements, heap->max_size * 2 * sizeof(zval));
memset(heap->elements + heap->max_size, 0, heap->max_size * sizeof(zval));
heap->max_size *= 2;
}
/* sifting up */
for (i = heap->count; i > 0 && heap->cmp(&heap->elements[(i-1)/2], elem, cmp_userdata) < 0; i = (i-1)/2) {
heap->elements[i] = heap->elements[(i-1)/2];
}
heap->count++;
if (EG(exception)) {
/* exception thrown during comparison */
heap->flags |= SPL_HEAP_CORRUPTED;
}
ZVAL_COPY_VALUE(&heap->elements[i], elem);
}
具体类:
abstract class SplHeap implements Iterator , Countable {
/* Methods */
public __construct ( void )
abstract protected int compare ( mixed $value1 , mixed $value2 )
public int count ( void )
public mixed current ( void )
public mixed extract ( void )
public void insert ( mixed $value )
public bool isEmpty ( void )
public mixed key ( void )
public void next ( void )
public void recoverFromCorruption ( void ) // 官方解释为Recover from the corrupted state and allow further actions on the heap.
public void rewind ( void )
public mixed top ( void )
public bool valid ( void )
}
需要注意的是:
add 是5.5+版本所有函数都是5.3+
从数据结构中可以看出,compare是一个抽象函数,所以只要实现compare比较函数就行。通过insert函数可以看出来,堆使用数组来实现的,默认申请PTR_HEAP_BLOCK_SIZE=64个大小的内存指针,当指针数组大小不够是,按两倍的方式递增申请。
具体函数详细可参考官方文档参考