数据结构——数组

数组定义:

在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识。

因为数组内的元素是连续存储的,所以数组中元素的地址,可以通过其索引计算出来。

性能空间占用

java中所有对象的大小都是8字节的整数倍,不足的要用对齐字节补足

随机访问

即根据索引查找元素,时间复杂度是O(1)

动态数组
java 复制代码
 private int size; // 逻辑大小
    private int capacity=8; // 容量
    private int[] array=new int[capacity];
插入
java 复制代码
//向最后的位置[size]添加元素
 public void addLast(int element){
        array[size]=element;
        size++;
    }
java 复制代码
//向[0....size]位置添加元素
    public void add(int index,int element){
        //未考虑数组扩容问题
        if(size>=0&&index<size) {
            //进行一个拷贝
            System.arraycopy(array, index, array, index + 1, size - index);
            array[index] = element;
            size++;
        } else if(index==size){//addLast
            array[index]=element;
            size++;
        }

    }
java 复制代码
public void add1(int index,int element){
        if(size >= 0 && index < size){
            System.arraycopy(array,index,array,index+1,size-index);
        }
        array[index]=element;
        size++;
    }
查询和遍历元素
java 复制代码
    //查询元素
    public int get(int index){//[0....size]
        return array[index];
    }
    //打印每个元素
    public void foreach(){
        for (int i=0;i<size;i++){
            System.out.println(array[i]);
        }
    }

    //函数式接口
    //遍历方法1,consumer接口 遍历执行的操作,每个元素入参
    public void foreach1(Consumer<Integer> consumer){
       for(int i=0;i<size;i++){
           consumer.accept(array[i]);
       }
    }

    //Iterator 是个接口,要有实现类
    //迭代器遍历
    @Override
    public Iterator<Integer> iterator() {
        //java里叫匿名内部类
        return new Iterator<Integer>() {
            int i=0;
            @Override
            public boolean hasNext() {//有没有下一个严肃
                return i<size;
            }

            @Override
            public Integer next() {//返回当前元素,并移动到下一个元素
                return array[i++];
            }
        };
    }

    public IntStream stream(){
        //IntStream 传的数字不仅有有效数字,还有无效的 eg:1,2,3,4,0,0,0,0
        return IntStream.of(Arrays.copyOfRange(array,0,size));
    }
java 复制代码
  public static void main(String[] args) {

        System.out.println("Hello world!");
        DynamicArray dynamicArray = new DynamicArray();
        dynamicArray.addLast(1);
        dynamicArray.addLast(2);
        dynamicArray.addLast(3);
        dynamicArray.addLast(4);


        dynamicArray.add(2,5);
        for(int i=0;i<5;i++){
            System.out.println(dynamicArray.get(i));
        }


        //迭代器遍历
        for(Integer element:dynamicArray){//hasnext()、next()方法
            System.out.println(element);
        }
    }
删除
java 复制代码
 public int remove(int index){  //[0...size]
        int removed=array[index];
        if(index<size-1) {
            //java数组中移动元素的方法
            System.arraycopy(array, index + 1, array, index, size - index - 1);
        }
        size--;
        return removed;
    }

对比数据是否一致(断言)

assertEquals(3,removed);

assertIterable(List.of(1,2,4,5),dynamicArray);

容量不够,先扩容
java 复制代码
   private void checkAndGrow() {
        //容量检查
        if(size==0){
            array=new int[capacity];
        }
        if(size==capacity){
            //进行扩容,1.5   1.618   2
            capacity+=capacity>>1;
            int [] newArray=new int[capacity];
            System.arraycopy(array,0,newArray,0,size);
            array=newArray;
        }
    }

插入或删除性能

头部位置,时间复杂度是O(n)

中间位置,时间复杂度是O(n)

尾部位置,时间复杂度是O(1)

全部代码

java 复制代码
package org.example;

import java.util.Iterator;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.stream.IntStream;

//动态数组
public class DynamicArray implements Iterable<Integer>{
    private int size; // 逻辑大小
    private int capacity=8; // 容量
   // private int[] array=new int[capacity];
   private int[] array={};


    //向最后的位置[size]添加元素
    public void addLast(int element){
        array[size]=element;
        size++;
    }

    //向[0....size]位置添加元素
    public void add(int index,int element){
        checkAndGrow();


        //未考虑数组扩容问题
        if(size>=0&&index<size) {
            //进行一个拷贝
            System.arraycopy(array, index, array, index + 1, size - index);
            array[index] = element;
            size++;
        } else if(index==size){//addLast
            array[index]=element;
            size++;
        }

    }

    private void checkAndGrow() {
        //容量检查
        if(size==0){
            array=new int[capacity];
        }
        if(size==capacity){
            //进行扩容,1.5   1.618   2
            capacity+=capacity>>1;
            int [] newArray=new int[capacity];
            System.arraycopy(array,0,newArray,0,size);
            array=newArray;
        }
    }

    public void add1(int index,int element){
        if(size >= 0 && index < size){
            System.arraycopy(array,index,array,index+1,size-index);
        }
        array[index]=element;
        size++;
    }

    //查询元素
    public int get(int index){//[0....size]
        return array[index];
    }
    //打印每个元素
    public void foreach(){
        for (int i=0;i<size;i++){
            System.out.println(array[i]);
        }
    }

    //函数式接口
    //遍历方法1,consumer接口 遍历执行的操作,每个元素入参
    public void foreach1(Consumer<Integer> consumer){
       for(int i=0;i<size;i++){
           consumer.accept(array[i]);
       }
    }

    //Iterator 是个接口,要有实现类
    //迭代器遍历
    @Override
    public Iterator<Integer> iterator() {
        //java里叫匿名内部类
        return new Iterator<Integer>() {
            int i=0;
            @Override
            public boolean hasNext() {//有没有下一个严肃
                return i<size;
            }

            @Override
            public Integer next() {//返回当前元素,并移动到下一个元素
                return array[i++];
            }
        };
    }

    public IntStream stream(){
        //IntStream 传的数字不仅有有效数字,还有无效的 eg:1,2,3,4,0,0,0,0
        return IntStream.of(Arrays.copyOfRange(array,0,size));
    }

    public int remove(int index){  //[0...size]
        int removed=array[index];
        if(index<size-1) {
            //java数组中移动元素的方法
            System.arraycopy(array, index + 1, array, index, size - index - 1);
        }
        size--;
        return removed;
    }


}
二维数组

从行开始遍历比从列开始遍历更快。

局部性原理:(空间方面)

cpu读取内存(速度慢)数据后,会将其放入高速缓存(速度快)中当中,如果后来的计算机再用到此数据,在缓存中能读到的话,就不必读内存了。

缓存的最小存储单位是缓存行,一般是64bytes,一次读的数据少了不划算,因此最少读64bytes填满一个缓存行,因此读入某一个数据时也会读取其临近的数据,这就是所谓的空间局部性。

相关推荐
wen__xvn10 分钟前
代码随想录算法训练营DAY6第三章 哈希表part01
数据结构·算法·散列表
漫随流水10 分钟前
leetcode算法(239.滑动窗口最大值)
数据结构·算法·leetcode
sprintzer14 分钟前
12.26-1.5力扣字符串刷题
算法·leetcode·职场和发展
黛色正浓15 分钟前
leetCode-热题100-双指针合集(JavaScript)
javascript·算法·leetcode
Croa-vo26 分钟前
TikTok 系统设计 VO 面经:实时热门视频检测系统深度复盘(附求职助攻指南)
java·算法·leetcode·面试·职场和发展
八月的雨季 最後的冰吻34 分钟前
FFmepg-- 41-ffplay源码- -快进快退seek
c++·算法·音视频
Swift社区36 分钟前
LeetCode 466 统计重复个数
算法·leetcode·职场和发展
橘颂TA42 分钟前
【剑斩OFFER】算法的暴力美学——字母异位词分组
数据结构·算法·leetcode·力扣·哈希算法·散列表·结构与算法
一把小椅子1 小时前
超大规模多模态交通数据集:320TB+海量数据资源,涵盖行车视频、无人机航拍、第一视角步行骑行与道路监控,助力自动驾驶与智慧交通算法突破
算法·自动驾驶·无人机
闻缺陷则喜何志丹1 小时前
【二分查找 图论】P10206 [JOI 2024 Final] 建设工程 2|普及+
c++·算法·二分查找·图论·洛谷