PHP SPL 数据结构笔记摘要

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个大小的内存指针,当指针数组大小不够是,按两倍的方式递增申请。

具体函数详细可参考官方文档参考



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值