数组是数据结构中最简单,也是使用最广泛的一种。在原生的js中,数组给我们提供了很多方便的操作方法,比如push(), pop(), shift(), unshift()。但是出于对数据结构的学习,我们将不使用这些已有的方法,而是自己实现这些方法。这样也方便我们计算其时间复杂度。这里我们选择使用TypeScript实现,主要是因为TypeScript的强类型控制,以及泛型这些高级特性。

先来看我们自己实现数组的实例属性以及构造函数,我们用capacity来表示数组的容量,虽然在TypeScript中并没有像Java那样严格限定数组长度,但我们仍然希望尽量接近Java。我们用size来表示当前数组中元素的个数

class MyArray<T> {
    private data: Array<T>;
    private size: number = 0;
    constructor(capacity = 10) {
        this.data = new Array(capacity);
    }
}

1.在数组中插入元素

在数组index位置插入元素是我们经常使用的一个操作,那我们就需要从之前数组中index位置开始,每个元素向后移动一个位置。以便给新插入的元素挪出位置。在操作的末尾,我们需要维护一下数组的size.

public add(index: number, e: T) {
    if (index < 0 || index > this.size) {
        throw new Error('Add failed. Required index >= 0 and index <= size.');
    }
    if (this.size === this.data.length) {
        this.resize(2 * this.data.length);
    }
    for (let i = this.size - 1; i >= index; i--) {
        this.data[i + 1] = this.data[i];
    }
    this.data[index] = e;
    this.size++;
}

在数组中添加元素,最好情况下,用户只用操作一次,时间复杂度是O(1);最差的情况下,用户需要操作size次,时间复杂度是O(n)

这里有一点需要注意,当数组当前元素的个数size和capacity相等时,我们需要给数组进行扩容为2倍处理,这个我后面会专门提及

2.在数组中查询元素和修改元素

这个没啥好说的,查询和修改数组中某个元素复杂度就是O(1)

public get(index: number): T {
    if (index < 0 || index >= this.size) {
        throw new Error('Get failed. Index is illegal.');
    }
    return this.data[index];
}

3.在数组中删除元素

在数组index位置删除元素,这里我们需要把数组从index+1位置开始,每个元素向前移动一个元素

public remove(index: number): T {
    if (index < 0 || index >= this.size) {
        throw new Error('Remove failed. Index is illegal.');
    }
    let ret = this.data[index];
    for (let i = index + 1; i < this.size; i++) {
        this.data[i - 1] = this.data[i];
    }
    this.size--;
    this.data[this.size] = undefined;
    // 如果数组中的元素仅为数组容量的1/4时,这时需要进行缩容操作
    if (this.size === this.data.length / 4 && this.data.length / 2 !== 0) {
        this.resize(this.data.length / 2);
    }
    return ret;
}

在数组中删除元素,最好情况下,用户只用操作一次,时间复杂度是O(1);最差的情况下,用户需要操作size次,时间复杂度是O(n)
当数组中的元素个数仅为数组容量的1/4时,我们需要对数组进行缩容为1/2操作

4.数组的扩容或者缩容

数组的扩容和缩容操作很简单,原理就是接受一个新的容量,把之前数组中的内容复制到新数组中,并返回新的数组

private resize(newCapacity: number): void {
    let newData = new Array(newCapacity);
    for (let i = 0; i < this.size; i++) {
        newData[i] = this.data[i];
    }
    this.data = newData;
}

更多相关数据结构,可以前往我的github。持续更新中,喜欢的话给个star~

TypeScript算法与数据结构-数组篇的更多相关文章

  1. TypeScript算法与数据结构-栈篇

    本文的源码在这里,可以参考一下 栈也是一种使用非常广泛的线性数据结构,它具有后进先出last in first out的特点.通俗的例子就像我们平时一本一本的往上放书,等到我们又想用书时,我们首先接触 ...

  2. java数据结构----数组篇

    1.数组作为java常用的数据结构之一,使用相对简单,下图展示了数组常用操作在允许和不允许重复值的情况下的比较次数 2.进行封装后的代码: package com.cn.higharray; /** ...

  3. TypeScript算法与数据结构-队列和循环队列

    本文涉及的源码,均在我的github.有两部分队列和循环队列.有问题的可以提个issue,看到后第一时间回复 1. 队列(Queue) 队列也是一种线性的数据结构, 队列是一种先进先出的数据结构.类似 ...

  4. 用js来实现那些数据结构(数组篇01)

    在开始正式的内容之前,不得不说说js中的数据类型和数据结构,以及一些比较容易让人混淆的概念.那么为什么要从数组说起?数组在js中是最常见的内存数据结构,数组数据结构在js中拥有很多的方法,很多初学者记 ...

  5. Python算法与数据结构--求所有子数组的和的最大值

    Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室-玄魂 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个 ...

  6. 用js来实现那些数据结构01(数组篇01-数组的增删)

    在开始正式的内容之前,不得不说说js中的数据类型和数据结构,以及一些比较容易让人混淆的概念.那么为什么要从数组说起?数组在js中是最常见的内存数据结构,数组数据结构在js中拥有很多的方法,很多初学者记 ...

  7. 数据结构与算法 基于c语言篇

    学习数据结构与算法走向深蓝之路 第一章:数据结构与算法概念型 数据结构:数据之间的相互关系,即是数据的组织形式. 基本组成:{ 数据:信息的载体 数据元素:数据基本单位: } 其结构形式有四种: 1, ...

  8. 算法与数据结构基础 - 数组(Array)

    数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...

  9. 【持续更新】leetcode算法-数组篇

    会在近期陆续地完成数组篇的整理,希望对找工作的小伙伴有所帮助.   1.Two Sum:两数相加为一固定值,求其下标.一次遍历数组,用一个hash表存储已经访问过的数及其下标,对于新访问的数value ...

随机推荐

  1. Qt Installer Framework 3.0.1 Released(功能比较强)

    We are happy to announce the release of Qt IFW 3.0.1. 3.0.1 is fully compatible with 2.0.5, which me ...

  2. win7在USB该解决方案不健全音箱

    Win7安装后,原XP在正常工作USB小喇叭不工作,重新安装声卡驱动程序仍然是相同的.后来,通过以下的得心应手最后一次尝试. 1.右键右下角喇叭button. 2.点击"播放设备" ...

  3. Oracle召回

    后几集录制视频,记录在记录开始的时候不知道怎么,录了几集没有什么,够又一次录,过程中也也把Oracle数据库这部分看了一遍,收获也挺多的,学习是反复积累的过程,对于一些零散的知识点又回想了一下,又一次 ...

  4. [bug系列]Method not found: 'Void Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommandBuilderFactory

    bug由来 最近开始学习NetCore,想通过实战使用NetCore做一个集成数据库存储Redis缓存的WebApi项目,由于MSSQL的庞大体积,最终决定使用轻量级关系型数据库MySql. 所以最终 ...

  5. Expression Blend实例动画-大坝水位升高演示

    原文:Expression Blend实例动画-大坝水位升高演示 Expression Blend是个很强大的东西,用它可以完成很多不好做的动画效果. 动画的主要元素: 时间线(Timeline) : ...

  6. Window 下 MySQL 环境的安装

    Window 下 MySQL 环境的安装 简介: MySQL 是最流行的关系型数据库管理系统,在WEB应用方面 MySQL 是最好的RDBMS(Relational Database Manageme ...

  7. 程序定义了多个入口点。使用 /main (指定包含入口点的类型)进行编译

    原文:请使用/main进行编译,以指定包含入口点类型 在使用VS工具初学C#的时候需要不停的写小程序,觉得每次都新建项目太过麻烦,所以试着把程序写在一个项目下面,结果编译的时候出错了,因为我每个小程序 ...

  8. linq中不能准确按拼音排序

    在LinqToObject中,利用OrderBy/OrderByDescending, ThenBy/ThenByDescending这4个方法排序时,发现不能正确的按拼音排序,所以在排序时增加编码支 ...

  9. WPF应用程序如何重启当前的Application

    // Restart current process Method 1 System.Windows.Forms.Application.Restart(); Application.Current. ...

  10. Tobject 类解析

    TObject = class    //创建    constructor Create;    //释放    procedure Free;    //初始化实列    class functi ...