定义

php 的数组 array 默认是动态的数据结构,而底层数组应该是在内存中开辟一块固定容量的存储空间,存储一段连续的数据,所以我们只能用 SplFixedArray 限制内存容量。

代码

github 地址:数组 (Arrays)

class Arrays
{
    private $data;
    private $size;
    private $capacity;
    // 构造函数,传入数组的容量 capacity 构造 Array, 默认数组的容量 capacity=10
    public function __construct(int $capacity = 10)
    {
        $this->data = new SplFixedArray($capacity);
        $this->capacity = $capacity;
        $this->size = 0;
    }
    // 获取数组中的元素个数
    public function getSize():int
    {
        return $this->size;
    }
     // 返回数组是否为空
    public function isEmpty():bool
    {
        return $this->size == 0;
    }
    // 获取数组的容量
    public function getCapacity():int
    {
        return $this->data->getSize();
    }
    // 在 index 索引的位置插入一个新元素 e O(n)
    public function add(int $index,int $e)
    {
        if($index <0 || $index > $this->size){
            throw new Exception("index is illegal");
        }
        if ($this->size == $this->capacity){
            $this->resize(2 * $this->capacity);
        }
        for ($i=$this->size -1 ; $i >=$index; $i--) {
            $this->data[$i + 1] = $this->data[$i];
        }
        $this->data[$index] = $e;
        $this->size ++;

    }
    // 向所有元素后添加一个新元素 O(1)
    public function addLast($e)
    {
        $this->add($this->size,$e);
    }
    // 在所有元素前添加一个新元素 O(n)
    public function addFirst($e)
    {
        $this->add(0,$e);
    }
    // 获取 index 索引位置的元素 O(1)
    public function get($index)
    {
        if($index <0 || $index > $this->size){
            throw new Exception("index is illegal");
        }
        return $this->data[$index];
    }
    public function getLast(){
        return $this->get($this->size-1);
    }
    public function getFirst(){
        return $this->get(0);
    }
    // 修改 index 索引位置的元素为 e O(1)
    public function set($index,$e)
    {
        if($index <0 || $index > $this->size){
            throw new Exception("index is illegal");
        }
        $this->data[$index] = $e;
    }
    // 查找数组中是否有元素 e O(n)
    public function contains($e):bool
    {
        for ($i=0; $i < $this->size; $i++) {
            if($this->data[$i] == $e){
                return true;
            }
        }
        return false;
    }
    // 查找数组中元素 e 所在的索引,如果不存在元素 e,则返回 -1 O(n)
    public function find($e):int
    {
        for ($i=0; $i < $this->size; $i++) {
            if($this->data[$i] == $e){
                return $i;
            }
        }
        return -1;
    }
    // 从数组中删除 index 位置的元素,返回删除的元素
    public function remove($index)
    {
        if($index <0 || $index > $this->size){
            throw new Exception("index is illegal");
        }
        $ret = $this->data[$index];

        for ($i=$index+1; $i < $this->size; $i++) {
            $this->data[$i-1] = $this->data[$i];
        }
        $this->size--;
        unset($this->data[$this->size]);
        if($this->size == $this->capacity / 4 && $this->capacity /2 != 0){
            $this->resize($this->capacity/2);
        }
        return $ret;
    }
     // 从数组中删除最后一个元素,返回删除的元素
    public function removeLast()
    {
        $this->remove($this->size-1);
    }
    // 从数组中删除第一个元素,返回删除的元素
    public function removeFirst()
    {
        $this->remove(0);
    }
     // 从数组中删除元素 e
    public function removeElement($e)
    {
        $index = $this->find($e);
        if($index != -1){
            $this->remove($index);
        }
    }
    // 将数组空间的容量变成 newCapacity 大小
    private function resize($newCapacity)
    {
        $newData = (new self($newCapacity))->data;
        for($i=0;$i<$this->size;$i++){
            $newData[$i] = $this->data[$i];
        }
        $this->data = $newData;
        $this->capacity = $newCapacity;
    }

    public function __toString()
    {
        $str = sprintf("\nArray: size = %d , capacity = %d\n",$this->size,$this->getCapacity());
        $str.='[';
        for($i = 0 ; $i < $this->size; $i ++){
            $str.= $i;
            if($i != $this->size - 1){
                $str.= ", ";
            }
        }
        $str.="]";
        return $str;
    }
}

时间复杂度

操作 注释 时间复杂度 说明
add 添加元素 O(n) 在最坏情况下要重新移动所有元素位置
addFirst 在头部添加元素 O(n) 最坏情况
addLast 在尾部添加元素 O(1) 最好情况
get 获取指定位置元素 O(1) 数据是连续的,能够直接根据位置获取到元素
getFirst 获取首个元素 O(1) 同上
getLast 获取末尾元素 O(1) 同上
set 修改指定索引位置的元素 O(1) 同上
contains 查找数组中是否有元素 O(1) 需要循环查找
find 查找数组中元素所在的索引 O(1) 需要循环查找
remove 删除指定元素 O(n) 在最坏情况下要重新移动所有元素位置
removeFirst 删除首个元素 O(n) 最坏情况
removeLast 删除末尾元素 O(1) 最好情况
removeElement 删除指定元素 O(1) 需要循环查找

总结

数组是最基础的数据结构,所以理解数组的原理和操作时间复杂度是深入学习数据结构和算法的基础。

欢迎扫描下方二维码,持续关注:

互联网工程师(id:phpstcn),我们一起学习,一起进步


徐石头
39 声望3 粉丝

一个web开发者