基础数据结构(一) 数组

基础数据结构(一):数组

面试经典:

​ 给你一个文件里面包含全国人民的年龄数据,现在要你统计每一个年龄有多少人?
给定机器为单台+2CPU+2G内存。不得使用现成的容器,比如map等

​ 在以上情况下你该如何以最高效的方法来解决这个问题?

解题思路

首先排序算法能否使用呢?遍历

从算法时间复杂度分析 最快O(N) N=14亿 想象一下能排的出来吗?

并且内存不够(6G塞不了2G)

这时候我们就能使用一种非常简单的方法处理 【数组算法】

全国人民 14亿

年龄 0~180

int data [] = new int[180];

这不就OK了吗?

data[0]++; // 0 岁人加一  data[0] 的值就表示0岁有多少人

下面看代码 (最主要的就是读取文件时一行一行读)

InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "UTF-8");
BufferedReader br = new BufferedReader(isr);
int tot = 0 ;	//21亿
int data [] = new int[200];
while((str = br.readLine()) != null){		//一行一行的读 O(n)
    int age = Integer.parseInt(str);
    data[age] ++ ;
    tot ++ ;
}

这里突出的就是数组的一个最优特点【下标】

数组是什么?

  • 有序的元素序列
  • 用于存储多个同类型数据的集合 通常使用【Array】表示 也叫做线性表

数组特点

  • 数组是相同数据类型的元素的集合。
  • 数组中的各元素的存储是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起。内存地址
  • 数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a[0]表示名字为a的数组中的第一个元素,a[1]代表数组a的第二个元素,以此类推。

数组表现形式

int[] a; // 一维数组
int[][] b; // 多维数组

随机访问

数组是连续的内存空间和相同类型的数据

正是因为这两个限制,它才有了一个非常重要的特性:【随机访问】

但有利就有弊,这两个限制也让数组的很多操作变得非常低效,

比如要想在数组中删除、插入一个数据,为了保证连续性,就需要做大量的数据搬移工作。

随机访问的重要应用:查找,面试重点

如何实现一个数组的增删改查?

package model;

/**
 * @author : ywb
 * @date : 2022-04-12 14:01
 */
public class MyArray {
    final int size;		//数组的长度
    final int[] data;
    private int index;		//当前已经存的数据大小

    public MyArray(int size) {
        this.size = size;
        data = new int[size];		//分配的内存空间{0,0,0,0,0}
        index = 0;
    }
    public void print(){
        System.out.println("index:" + index);
        Arrays.stream(data).forEach(System.out::print);
        System.out.println();
    }
    public void insert(int loc,int n){		//时间复杂度 O(n);
        if(index ++ < size){
            for(int i = size - 1; i > loc ; i --){	//为什么不能写size 0~size-1 如果loc是0 O(n),O(1)=>O(n)
                data[i] = data[i - 1];	//把数据往后移一个
            }
            data[loc] = n;
        }
        //扩容 会把size*2 0.75
    }
    public void delete(int loc){	//O(n)
        for(int i = loc ; i < size ; i++){
            if(i != size - 1){		//怕越界所以加一个判断
                data[i] = data[i + 1];
            }else{
                data[i] = 0;			//默认为0 就是没存数据的
            }
        }
        index -- ;
    }

    public void update(int loc,int n){  //O(1)
        data[loc] = n;
    }

    public int get(int loc){		//O(1)
        return data[loc];
    }
}

实现总结

根据实现可以看出

插入 删除 属于复制新数组 数据挪移 时间复杂度O(n)

查询 修改 使用下标访问 时间复杂度O(1)

所以 【增删】慢 【查改】 快

下面来说下ArrayList吧?

ArrayList 和数组

首先本质都是一样的 数组

但是ArrayList 是JDK封装了。不需要管扩容等操作

数组的话就要你全部操作

两者之间应该如何选用?

不知道数据大小的肯定选ArrayList.

如果你知道数据的大小而且你又非常关注性能那就用数组。

总结

数组是一个最基础最简单的数据结构

它是存储相同类型的一组数据,最大的两个特点就是

【下标】和【随机访问】缺点就是插入和删除是很慢的,时间复杂度为O(n)。

posted @   火力彬  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示