」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 實現動態數組

實現動態數組

發佈於2024-07-31
瀏覽:598

Implementing Dynamic Arrays

假设理解 Big O 表示法。 JavaScript 中有示例。信息参考 Gayle Laakmann McDowell 的《Cracking the Coding Interview》

介绍

在 JavaScript 或 Python 等某些语言中,数组会自动调整大小,这意味着数组会随着您追加项目而增长。在 Java 等其他语言中,数组是固定长度的,这意味着数组的大小是在初始化数组时定义的。这些自动增长的数组称为动态数组

了解动态数组

在 Java 中,ArrayList 是一种类似数组的数据结构,它提供动态调整大小,同时仍然提供 O(1)O(1) O(1) 使用权。当数组已满时,数组的大小会加倍。每次加倍需要 O(n)O(n) 在) 时间,但发生的情况很少,因此其摊销插入时间仍然是 O(1)O(1) O(1) .

在不同的编程语言中,该数据结构的名称及其调整大小因子(Java 中为 2)各不相同。调整大小因子决定数组大小将调整多大。

为什么是摊销插入时间 O(1)O(1) O(1)

调整大小时,假设调整大小因子为 2,我们可以观察到,通过将前一个数组加倍(即 N 的一半),我们将数组增加到大小为 N 的数组。此外,我们还需要复制 N/2N/2N/2 元素添加到这个新数组。

如果我们将从最终容量增加到第一次容量增加复制的元素数量相加: n2 n4 n8 n 16 ... 2 1\frac{n}{2} \frac{n}{4} \frac{n}{8} \frac{n}{16 } ... 2 12n 4n 8 n 16n ... 2 1 其总和略小于 N。因此,插入 N 个元素大约需要 O(n)O(n) 在) 总共工作。每次插入都是 O(1)O(1) O(1) 平均而言,即使某些插入需要 O(n)O(n) 在) 最坏情况下的时间。

核心概念和大O复杂性

JavaScript中的动态数组通常有几个核心方法,每个方法都有不同的时间复杂度:

get(i):该方法检索索引 i 处的元素。

  • 复杂: O(1)O(1) O(1)

set(i, n):该方法将索引 i 处的元素设置为 n。

  • 复杂: O(1)O(1) O(1)

pushback(n):该方法将元素n添加到数组末尾。

  • 复杂: O(1)O(1) O(1) 摊销,但是 O(n)O(n) 在) 当调整大小时

popback():该方法删除数组的最后一个元素。

  • 复杂: O(1)O(1) O(1)

resize():该方法将数组的容量加倍,并将所有元素复制到新数组。

  • 复杂: O(n)O(n) 在)

getSize():该方法返回数组中元素的数量。

  • 复杂: O(1)O(1) O(1)
  • 注意:我们可以通过使用大小变量来跟踪数组中已填充槽的数量来实现这种复杂性。

getCapacity():该方法返回数组的当前容量。

  • 复杂: O(1)O(1) O(1)

JavaScript 中的实现

class DynamicArray {
    // size is # of filled slots while capacity is total slots in array
    constructor(capacity) {
        this.capacity = capacity;
        this.arr = new Array(this.capacity);
        this.size = 0;
    }

    // O(1)
    get(i) {
        if (i = this.size) return undefined;
        return this.arr[i];
    }

    // O(1)
    set(i, n) {
        if (i = this.size) return undefined;
        this.arr[i] = n;
    }

    // O(1) amortized 
    pushback(n) {
        if (this.size === this.capacity) {
            this.resize();
        }
        this.arr[this.size] = n;
        this.size  ;
    }

    // O(1) 
    popback() {
        if (this.size === 0) return undefined;
        this.size--;
        let temp = this.arr[this.size];
        this.arr[this.size] = undefined;
        return temp;

    }

    // O(n)
    resize() {
        this.capacity *= 2;
        let newArr = new Array(this.capacity);
        for (let i = 0; i 



结论

动态数组是一种强大的数据结构,它结合了可调整存储大小的灵活性和恒定时间访问的效率。希望这可以帮助!

版本聲明 本文轉載於:https://dev.to/jihoonj/implementing-dynamic-arrays-5fb5?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3