数组是数据结构中最简单,也是使用最广泛的一种。在原生的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. Ubuntu 14.04 64位字体美化(使用黑文泉驿)

    Ubuntu 14.04安装和升级后,,斜体字体变得很难看,昨天,我得到一个晚上,最终,管理一个线索,这里整洁. 在线调研后,.一致的观点是,,使用开源字体库文泉驿理想的黑色字体效果,效果甚至没有丢失 ...

  2. [Unity3D]Unity3D圣骑士模仿游戏开发传仙灵达到当局岛

    大家好,我是秦培.欢迎关注我的博客.我的博客地址blog.csdn.net/qinyuanpei. 在前面的文章中.我们分别实现了一个自己定义的角色控制器<[Unity3D]Unity3D游戏开 ...

  3. 阿里将成为下一个谷歌?是谁Google真正的挑战者

    非常多观点觉得阿里下一步即将成为google的挑战者,但不管从技术储备还是产业布局来看,阿里都难当此任.在产业模式上.电商挑战搜索尚有诸多短板,在解决这些根本问题前,空泛谈论这些是没有意义的. < ...

  4. WPF 跨界面调用程序

    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (System.Threading.ThreadStart)delegate() { sE ...

  5. Asp UserInfoList 方法二

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UserInfoList.a ...

  6. Android之运行时相机权限和联系人权限获取

    原文:Android之运行时相机权限和联系人权限获取 本文链接:http://blog.csdn.net/qq_16628781/article/details/61623502 Android之运行 ...

  7. Gradle离线配置

    原文:Gradle离线配置 1. 先在Gradle官网下载最新的离线zip压缩包. https://gradle.org/ 2. 将下载的zip压缩包,保存到本地磁盘下的目录中. 3. 修改(grad ...

  8. Django 下添加左侧字段显示和搜索

    在对应的apps下建立xadmin.py from .models import EmailVerifyRecord import xadminclass EmailVerifyRecordAdmin ...

  9. 在DELPHI中*.wav 文件怎么加到资源文件中

    比较“流行”的说法是:“16位的Delphi   1.0和32位的Delphi2.0.3.0都提供了资源         编译工具,其中   Delphi   1.0的资源编译器叫BRCC.EXE,D ...

  10. vs编译在win xp电脑上运行的win32程序遇到的问题记录(无法定位程序输入点GetTickCount64于动态链接库KERNEL32.dll)

    直接编译后运行,弹出提示框:不是有效的win32应用程序 像之前那样把msvcr110.dll复制过去依然报错: 这是因为vs2012编译的win32程序用到的系统函数在xp环境上对应不上.之前转载的 ...