数据结构基础之数组

1.算法概述

算法:在计算机领域里,算法是一系列程序指令,用于处理特定的运算和逻辑问题。衡量算法优劣的主要标准是时间复杂度和空间复杂度。
数据结构:数据的组织、管理和存储格式,其使用的目的是为了高效的访问和修改数据。数据结构包含数组、链表这样的线性数据结构,也包含树、图这样的复杂数据结构。
时间复杂度:对一个算法运行时间长短的量度,用O表示,记作T(n)=O(f(n))
空间复杂度:对一个算法在运行过程中临时占用存储空间大小的量度用O表示,记作S(n)=O(f(n))。其中递归算法的空间复杂度和递归深度成正比。

2. 数组

2.1 数组的概念

数组对应的英文是array,是有限个相同类型的变量所组成的有序集合,数组中的每一个变量被称为元素。数组是最为简单、最为常用的数据结构。

数组的另一个特点,是在内存中顺序存储,因此可以很好地实现逻辑上的顺序表。

内存是由一个个连续的内存单元组成,每一个内存单元都有自己的地址。在这些内存单元中,有些被其他数据占用了,有些是空闲的。
在这里插入图片描述
如图,橙色格子代表空闲的存储单元,灰色格子代表已占用的存储单元,红色的连续格子代表数组在内存中的位置。

2.2 数组的基本操作

1,读取元素
由于数组在内存中顺序存储,所以只要给出一个数组下标,就可以读取到对应的数组元素。

int[] array = new int[]{3,1,2,5,4,7,5,1,9};
//输出下标为3的元素
System.out.println(array[3]);

这种根据下标读取元素的方式叫随机读取

2,更新元素
把数组中某一个元素的值替换为一个新值。

int[] array = new int[]{3,1,2,5,4,7,5,1,9};
//给数组下标为3的元素赋值
array[3] = 10;

3,插入元素
存在三种情况:

  • 尾部插入:直接把插入的元素放在数组尾部的空闲位置上
  • 中间插入:先把插入位置及后面的元素向后移动,空出地方,再把要插入的元素放到对应的数组位置上
  • 超范围插入:一个长度固定的数组,已经装满了元素,这是还想插入一个新元素。这涉及到数组的扩容。扩容的方法:创建一个新数组,长度是旧数组的2倍,再把旧数组中的元素复制过来,这样就实现了数组的扩容。

中间插入操作的完整实现代码:

/**
 * 中间插入操作
 */
public class MyArray {
    private int[] array;
    private int size;

    public MyArray(int capacity){
        this.array = new int[capacity];
        size = 0;
    }

    /**
     * 数组插入元素
     * @param index     插入的位置
     * @param element   插入的元素
     */
    public void insert(int index,int element) throws Exception{
        //判断访问下标是否超出范围
        if (index<0 || index>size){
            throw new IndexOutOfBoundsException("超出数组实际元素范围!");
        }
        //从右向左循环,将元素逐个向右挪一位
        for (int i = size-1; i >= index ; i--) {
            array[i+1] = array[i];
        }
        //腾出的位置放入新元素
        array[index] = element;
        size++;
    }

    /**
     * 输出数组
     */
    public void output(){
        for (int i = 0; i < size; i++) {
            System.out.println(array[i]);
        }
    }

    public static void main(String[] args) throws Exception{
        MyArray myArray = new MyArray(10);
        myArray.insert(0,3);
        myArray.insert(1,7);
        myArray.insert(2,9);
        myArray.insert(3,5);
        myArray.insert(1,6);
        myArray.output();
    }
}

运行结果:在这里插入图片描述

超范围插入操作的完整实现代码:

/**
 *超范围插入
 */
public class MyArray {
    private int[] array;
    private int size;

    public MyArray(int capacity){
        this.array = new int[capacity];
        size = 0;
    }

    /**
     * 数组插入元素
     * @param index     插入的位置
     * @param element   插入的元素
     */
    public void insert(int index,int element) throws Exception{
        //判断访问下标是否超出范围
        if (index<0 || index>size){
            throw new IndexOutOfBoundsException("超出数组实际元素范围!");
        }
        //如果实际元素达到数组容量上限,对数组进行扩容
        if (size>=array.length){
            resize();
        }
        //从右向左循环,将元素逐个向右挪一位
        for (int i = size-1; i >= index ; i--) {
            array[i+1] = array[i];
        }
        //腾出的位置放入新元素
        array[index] = element;
        size++;
    }

    /**
     * 数组扩容
     */
    public void resize(){
        int[] arrayNew = new int[array.length*2];
        //从旧数组复制到新数组
        System.arraycopy(array,0,arrayNew,0,array.length);
        array = arrayNew;
    }

    /**
     * 输出数组
     */
    public void output(){
        for (int i = 0; i < size; i++) {
            System.out.print(array[i]);
            System.out.print("\t");
        }
    }

    public static void main(String[] args) throws Exception{
        MyArray myArray = new MyArray(4);
        myArray.insert(0,3);
        myArray.insert(1,7);
        myArray.insert(2,9);
        myArray.insert(3,5);
        myArray.insert(1,6);
        myArray.output();
    }
}

输出结果:
在这里插入图片描述
4,删除元素
数组的删除操作和插入操作的过程相反,如果删除的元素位于数组中间,其后的元素都需要向前挪动1位。

删除操作的代码:

	/**
     * 数组删除元素
     * @param index 删除的位置
     */
    public int delete(int index) throws Exception{
        if (index<0 || index>size){
            throw new IndexOutOfBoundsException("超出数组实际元素范围");
        }
        int deleteElement = array[index];
        for (int i = index; i < size-1 ; i++) {
            array[i] = array[i+1];
        }
        size--;
        return deleteElement;   //返回被删除的元素
    }

数组的优势和劣势

优势:拥有非常高效的随机访问能力,只要给出下标,就可以用常量时间找到对应的数组元素。二分查找就是利用数组的这个优势。

劣势:主要体现在插入和删除元素方面。由于数组元素连续紧密地存储在程序中,插入、删除元素都会导致大量元素被迫移动。

总的来说,数组所适合的是读操作多,写操作少的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值