美文网首页
数据结构 - 动态数组

数据结构 - 动态数组

作者: Super曲江龙Kimi | 来源:发表于2020-02-28 17:06 被阅读0次

数组在内存中是连续保存的,容量也是在一开始就确定的,很多编程语言中,数组都有个缺点就是不可以动态的修改容量。或者底层已经封装好了一套动态数组的数据结构。
自己实现动态数组:代码如下

const DEFAULT_CAPATICY = 10;
const ELEMENT_NOT_FOUND = -1;

class ArrayList {
    // 传入数组的容量
    constructor(capaticy = DEFAULT_CAPATICY) {
        this.elements = new Array(capaticy);
        this.size = 0;
    }

    // 清空
    clear() {
        this.elements = new Array(DEFAULT_CAPATICY);
        this.size = 0;
    }

    // 获取size
    getSize() {
        return this.size;
    }

    // 判断是否为空
    isEmpty() {
        return this.size === 0;
    }

    // 判断是否包含一个元素 平均复杂度:O(n)
    contains(ele) {
        return this.indexof(ele) !== ELEMENT_NOT_FOUND;
    }

    // 添加元素 平均复杂度:O(n)
    add(ele, index) {
        this.expandCapacity(this.size + 1);
        // 给index添加元素
        if (typeof index === 'number') {
            this.rangeCheck(index, true);
            // 添加元素后所有的数组都需要往后移动
            for (let i = this.size; i >= index; i--) {
                this.elements[i + 1] = this.elements[i];
                if (i === index) this.elements[i] = ele;
            }
            this.size++
        } else {
            // 给末尾添加元素
            this.elements[this.size++] = ele;
        }
    }

    // 获取固定下标的元素 平均复杂度:O(1)
    get(index) {
        this.rangeCheck(index);
        return this.elements[index];
    }

    // 设置固定下标的元素 平均复杂度:O(1)
    set(index, ele) {
        this.rangeCheck(index);
        this.elements[index] = ele;
    }

    // 删除固定下标的元素 平均复杂度:O(n)
    remove(index) {
        this.rangeCheck(index);

        let old = this.get(index);
        for (let i = index; i < this.size; i++) {
            if (i === this.size - 1) {
                this.elements[i] = null
            } else {
                this.elements[i] = this.elements[i + 1];
            }
        }
        this.size--;
        this.reduceCapacity();
        return old;
    }

    // 获取元素的下标 平均复杂度:O(n)
    indexof(ele) {
        for (let i = 0; i < this.size; i++) {
            if (this.elements[i] === ele) return i;
        }
        return ELEMENT_NOT_FOUND;
    }

    // 检查是否超出范围
    rangeCheck(index, isadd) {
        if (isadd) {
            if (index > this.size || index < 0) throw new RangeError('index is out of range');
        } else {
            if (index >= this.size || index < 0) throw new RangeError('index is out of range');
        }
    }
    // 缩容 -- 如果已使用的容量远小于数组的容量,需要缩容
    reduceCapacity() {
        let oldCapaticy = this.elements.length; // 5
        let newCapaticy = oldCapaticy >> 1; // 2

        if (newCapaticy < this.size || oldCapaticy <= DEFAULT_CAPATICY) return false;

        let elements = new Array(newCapaticy);
        for (let i = 0; i < this.size; i++) {
            elements[i] = this.elements[i];
        }
        this.elements = elements;

        console.log(`${oldCapaticy} -->缩容为--> ${newCapaticy}`);
    }

    // 扩容 -- 如果已使用的容量已经大于等于容量需要扩容
    expandCapacity(capaticy) {
        let oldCapaticy = this.elements.length;
        if (capaticy <= oldCapaticy) return false;

        let newCapaticy = oldCapaticy + (oldCapaticy >> 1);
        let elements = new Array(newCapaticy);

        for (let i = 0; i < this.size; i++) {
            elements[i] = this.elements[i];
        }
        this.elements = elements;

        console.log(`${oldCapaticy} -->扩容为--> ${newCapaticy}`);
    }

    toString() {
        return `${(this.elements || []).join(',')} --> size = ${this.size}`;
    }
}

动态数组的优点和缺点
优点:

  1. 查询和更新元素效率高,直接通过索引查找
  2. 开辟、销毁内存空间次数相对较少
    缺点:
  3. 删除和添加(非尾部) 元素时需要移位,而且需要动态扩容和缩容,效率较低
  4. 开辟空间后可能会造成空间浪费,不是开多少用多少。

相关文章

  • ArrayList和LinkList的区别

    ArrayList:是Array的数据结构,Array是动态数组,是对List接口的实现,他是数组队列,相当于动态...

  • 8.LinkedList

    ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。LinkedList不支...

  • 2020-07-16

    1、看完谷粒商城31 2、恋上数据结构之动态数组

  • 浅谈动态数组&数据结构(object-C)

    什么是数据结构? 接下来我们手写一个动态数组 首先动态数组的接口设计如下: 实现代码如下: #import ...

  • Redis源码

    一、Redis数据结构: SDS SDS(动态字符串)包含字符数组buf[],字符数组现有长度len,字符数组分配...

  • 数据结构与算法二(动态数组)

    目录一、什么是数据结构?二、线性表2.1 数组(Array)2.2 动态数组(Dynamic Array)接口设计...

  • ArrayList and LinkedList

    ArrayList and LinkedList ArrayList是实现了基于动态数组的数据结构,LinkedL...

  • ARTS-第二周

    Algorithm 从基础开始手写动态数组 git代码地址 数组定义:数组(Array)是一种线性表数据结构。它用...

  • 链表

    数组和链表的对比 前面提到的动态数组,栈和队列,底层依托的都是静态的数组这节涉及到的链表才是真正的动态数据结构 数...

  • 数据结构-链表

    前面创建的动态数组, 栈和队列底层都是依托于静态数组的,靠resize来解决容量问题.而链表是真正的动态数据结构....

网友评论

      本文标题:数据结构 - 动态数组

      本文链接:https://www.haomeiwen.com/subject/xfwlhhtx.html