线性表 - 数组

线性表 - 数组

1.1 数组的介绍

  • 数组(Array)有限个相同类型的变量所组成的有序集合,数组中的每一个变量被称为元素。数组是最为简单、最为常用的数据结构
    在这里插入图片描述

  • 数组下标从零开始(Why)

    • 存储原理

      • 数组用一组连续的内存空间来存储一组具有相同类型的数据
        在这里插入图片描述
      • 灰色格子被使用的内存
      • 橙色格子空闲的内存
      • 红色格子数组占用的内存
    • 数组可以根据下标随机访问数据
      在这里插入图片描述

      • 假设首地址是:1000,int是4字节(32位),实际内存存储是位,随机元素寻址

      • a[i]_address=a[0]_address+i*4
        
      • 该公式解释了三个方面

        • 连续性分配
        • 相同的类型
        • 下标从0开始(从 0 开始计算元素下标根据公式不需要偏移量,这也是数组下标从 0 开始的原因)

1.2 自己实现一个数组,并具有基本的操作方法

  • 创建默认大小的数组,或者是创建指定大小的数组
  • 对数组的元素进行增删改查的操作,其中增加支持顺序插入,指定索引的位置插入两种(需要向后移动元素)
/**
 * @author 云梦归遥
 * @date 2022/5/12 10:09
 * @description
 */
public class MyArray {
    private int[] array; //构建的数组对象
    private static final int ARRAY_LENGTH = 8; // 定义无参构造默认的数组长度
    private int length = 0; // 记录数组有效长度

    // 数组构造方法
    public MyArray(){// 默认构造方法数组长度为 8
        this.array = new int[ARRAY_LENGTH];
    }
    public MyArray(int len){// 有参构造则依靠传入的整型数字来构造数组
        this.array = new int[len];
    }

    // 增加数据
    // 默认插入是顺序插入
    public boolean insert(int num){
        if (length < array.length){
            array[length++] = num; // 插入到下一个位置
            return true;
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    // 还可以指定索引位置插入
    public boolean insert(int num, int index){
        if (length < array.length){
            int chance = 0; // 记录是否成功实现数组中元素的移动,从而实现挪出空位
            for (int i = index + 1; i < array.length - 1; i++){
                if (array[i] == 0){
                    for (int j = i; j > index; j--){
                        array[j] = array[j - 1];
                    }
                    chance++;
                    break;
                }
            }
            if (chance > 0){
                // 说明挪动位置成功
                array[index] = num; // 插入到指定位置
                ++length;
                return true;
            } else {
                // 说明挪动位置失败,即后面没有空格出现,插入失败
                return false;
            }
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    // 删除
    public boolean delete(int index){
        if (index < array.length && index >= 0){
            array[index] = 0; // 数组初始化后默认数值就是 0
            --length; // 有效长度 - 1
            return true;
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    // 修改
    public boolean update(int num, int index){
        if (index < array.length && index >= 0){
            array[index] = num; // 更新指定索引的数据
            return true;
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    // 查询
    public int select(int index){
        if (index < array.length && index >= 0){
            return array[index];
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    }

    // 数组的扩容(数组长度不够,需要进行扩容)
    public boolean resize(){
        try {
            // 将目前的数组进行 2 被放大
            int[] newArray = new int[array.length * 2];
            // 将原数组中的数据复制到新的数组中
            System.arraycopy(array, 0, newArray, 0, array.length);
            array = newArray;
            return true;
        } catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public String toString() {
        return "MyArray{" +
                "array=" + Arrays.toString(array) +
                '}';
    }
}

1.3 进行简单的测试

package com.lagou.test;

import com.lagou.entity.MyArray;

/**
 * @author 云梦归遥
 * @date 2022/5/12 10:45
 * @description
 */
public class MyArrayTest {
    public static void main(String[] args) {
        MyArray myArray = new MyArray(); // 默认数组,长度为 8
        myArray.insert(1);
        myArray.insert(2);
        myArray.insert(3);
        myArray.insert(4, 1);
        System.out.println(myArray.toString());
        myArray.update(5, 3);
        myArray.delete(0);
        System.out.println(myArray.toString());
    }
}

测试结果:
在这里插入图片描述

1.4 总结

  • 时间复杂度

    • 读取和更新都是随机访问,所以是O(1)
    • 插入数组扩容的时间复杂度是O(n),插入并移动元素的时间复杂度也是O(n),综合起来插入操作的时间复杂度是O(n)
    • 删除操作,只涉及元素的移动,时间复杂度也是O(n)
  • 优缺点

    • 优点:
      • 数组拥有非常高效的随机访问能力,只要给出下标,就可以用常量时间找到对应元素
    • 缺点:
      • 插入和删除元素方面。由于数组元素连续紧密地存储在内存中,插入、删除元素都会导致大量元素被迫移动,影响效率。 (ArrayList(数组实现,适合查询,更新) LinkedList(链表实现,适合插入,删除) )
      • 申请的空间必须是连续的,也就是说即使有空间也可能因为没有足够的连续空间而创建失败
      • 如果超出范围,需要重新申请内存进行存储,原空间就浪费了
  • 应用

    • 数组是基础的数据结构,应用太广泛了,ArrayList、Redis、消息队列等等
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值