基础数据结构(一) 数组
基础数据结构(一):数组
面试经典:
给你一个文件里面包含全国人民的年龄数据,现在要你统计每一个年龄有多少人?
给定机器为单台+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)。
本文来自博客园,作者:火力彬,转载请注明原文链接:https://www.cnblogs.com/ttbb123/p/16135033.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报