java动态数组的实现的_基于Java的动态数组分析与实现
动态数组
概念
基于Java提供的静态数组封装自己的动态数组,动态数组涉及的组成部分如下图所示。
组成部分解读data:静态数组,通过泛型支持多种类型的元素:private E[] data;。
size:数组的大小,作为数组的尾指针,在元素数量改变的时候务必维护指针的位置。size = maxIndex + 1
当数组为空,size = 0
当数组为满,size = capacity
capacity:数组的容量,不需要另外声明成员变量:capacity = data.length
动态数组的运算扩容操作public void resize(int newCapacity){
E[] newData = (E[]) new Object[newCapacity];
for(int i = 0; i < size; i++){
newData[i] = data[i];
}
data = newData;
}
添加操作在指定索引插入public void add(int index,E e){
//capacity = 数组的容量
if(size == data.length){
//throw new IllegalArgumentException("容量满了");
resize(2 * data.length);
}
//size = maxIndex + 1 ---> maxIndex = size - 1 输入的index > maxIndex + 1
if(index < 0 || index > size - 1 + 1){
throw new IllegalArgumentException("参数不符合要求");
}
//index以后的元素往后移动一位,并在index处插入元素e
for(int i = size - 1; i >= index; i--){ //i代表要移动的位置,所以i>=index都需要移动
data[i+1] = data[i];
}
data[index] = e;
size++; //维护尾指针
}在动态数组头插入public void addFirst(E e){
add(0,e);
}在动态数组尾插入public void addLast(E e){
add(size,e); //size指向最大索引元素后的一个元素
}
删除操作删除指定索引元素public E remove(int index){
if(index < 0 || index > size -1){
throw new IllegalArgumentException("参数不合法");
}
E ret = data[index]; //疏忽:删除应该返回删除元素
for(int i = index; i < size - 1; i++){
data[i] = data[i+1];
}
size--;
data[size] = null; //疏忽:清空最后一个元素,为了让垃圾回收机制回收
//重新调整容量
//当前数组元素个数 == 容量的1/4
if(size == data.length / 4 && data.length /2 != 0){ //原本是/2 解决复杂度震荡
resize(data.length / 2);
}
return ret;
}删除头索引元素public E removeFirst(){
return remove(0);
}删除尾索引元素public E removeLast(){
return remove(size-1);
}根据元素的值删除元素public void removeElement(E element){
int index = find(element);
if(index != -1){
remove(index);
}
}
修改操作public void set(int index,E e){
data[index] = e;
}
查询操作根据索引查public E get(int index){
return data[index];
}根据元素查,注意使用值比较public int find(E e){
for(int i = 0; i < size; i++){ //注意遍历终止条件不是size - 1
if(data[i].equals(e)){ //不用引用比较,值比较更合理
return i;
}
}
return -1;
}是否包含某个元素public boolean contains(E e){
//先找出索引
int index = find(e);
//判断索引是否存在
return index != -1;
}
时间复杂度分析
最坏复杂度
问:如果只对最后一个元素操作依然是O(n)?因为resize? 答:是的。
均摊复杂度
下面是对增加操作addLast均摊复杂度分析。
案例分析:在这个案例中,使用9次addLast操作,会触发一次resize,会进行(8 + 8 + 1 = 17)次基本操作;平均每次addLast操作,会进行(17 / 9 = 2)次基本操作
进一步推广,假如capacity = n,则n + 1次addLast操作,会触发一次resize,会进行(n + n + 1 = 2n + 1)次基本操作;平均每次addLast操作,会进行(2n + 1 / n + 1 = 2)次基本操作
最后得出结论,平均每次addLast操作,会进行2次基本操作,这样均摊计算,resize时间复杂度是O(1)的!这样比最坏复杂度更有意义
复杂度震荡
当数组容量capacity = n,也就是说数组容量的扩容和缩容的临界点都为n的时候,如果反复addLast和removeLast,会造成数组的不断扩容和缩容,这样会浪费时间,每次都需要O(n),发生震荡!出现问题的原因:removeLast时,resize过于着急
解决方案:对于增加操作,不够必须要扩容,但是对于删除操作,有多的空间不一定需要缩容。因此对于删除操作,可以使用Lazy的方案,也就是说更慢一点进行缩容。这也就是remove操作由size == data.length / 2修改为size == data.length / 4的原因。if(size == data.length / 4 && data.length /2 != 0){ //原本是/2 解决复杂度震荡
resize(data.length / 2);
}还有一个问题,为什么需要缩容到原来的一半,而不是四分之一?原因是防止执行增加操作的时候再需要扩容。
java动态数组的实现的_基于Java的动态数组分析与实现相关推荐
- java动漫网站开题报告_基于java的校园论坛网站的开发与设计开题报告.doc
基于java的校园论坛网站的开发与设计开题报告 太 原 科 技 大 学 华 科 学 院 毕业设计开题报告 学 生 姓 名:学 号:学 院.系:专 业:论 文 题 目:指导教师: 2015 年 3 月1 ...
- 用java写的教职工信息管理系统_基于Java的教师信息管理系统的设计与实现论文.doc...
基于Java的教师信息管理系统的设计与实现论文 职场大变样社区():下载毕业设计成品 全套资料,全部50元以下 毕业设计(论文)任务书 第1页 毕业设计(论文)题目: 基于java的教师信息管理系统的 ...
- Java简单记事本设计实验报告_基于JAVA的记事本设计报告.doc
基于JAVA的记事本设计报告 华北科技学院计算机系综合性实验报告 PAGE 第 PAGE 11 页 XX学校计算机系综合性实验 实 验 报 告 课程名称 Java程序设计 实验学期 至 学年 第 学期 ...
- java 金数据推送数据_基于JAVA的黄金数据接口调用代码实例
代码描述:基于JAVA的黄金数据接口调用代码实例 接口地址:http://www.juhe.cn/docs/api/id/29 1.[代码][Java]代码 import java.io.Buffer ...
- 基于java的oa协同办公系统_基于JAVA的OA系统的制作毕业设计论文
<基于JAVA的OA系统的制作毕业设计论文.doc>由会员分享,可免费在线阅读全文,更多与<基于JAVA的OA系统的制作毕业设计论文>相关文档资源请在帮帮文库(www.woc8 ...
- java用代码实现星期菜谱_基于JAVA的菜谱大全接口调用代码实例
基于JAVA的菜谱大全接口调用代码实例 代码描述:基于JA V A的菜谱大全接口调用代码实例 接口平台:聚合数据 import java.io.BufferedReader; import java. ...
- java拼图游戏设计文档_基于JAVA的拼图游戏的设计与实现(含录像)
基于JAVA的拼图游戏的设计与实现(含录像)(任务书,开题报告,中期检查表,外文翻译,毕业论文15500字,程序代码,答辩PPT,答辩视频录像) 摘 要 在我们日常生活中,有很多的益智类游戏,如七巧 ...
- Java创新创业讲座心得体会_基于Java?Web的创新创业管理系统设计与实现
第16卷 第2期 201 7年2月 软 件 导 刊 Softw arc Guide Vo1.16NO.2 Feb.20l7 基于 Java Web的创新创业管理系统设计与实现 张 泽 ,雷光 波 (湖 ...
- java坦克大战登录界面设计_基于JAVA的坦克大战设计和实现-代码.doc
JISHOU UNIVERSITY 本科生毕业设计 题 目:基于JAVA的坦克大战设计与实现作 者:学 号:所属学院:专业年级:指导教师:职 称:完成时间:2012年5月7日 吉首大学 基于JAVA的 ...
最新文章
- GoogleNet是怎么理解图像的?谷歌大神教你读懂「神经特征可视化」
- python文件读取数据-Python从文件中读取数据
- 一文深入浅出cv中的Attention机制
- 《算法竞赛入门经典》 例题 4-1 古老的密码(Ancient Cipher) UVa 1339
- Vue-router路由基础总结(一)
- Java 反射机制详解:私有方法调用头大?如何通过反射调用类中的私有方法?
- 判断linux进程是否存在
- selenium 三种断言以及异常类型
- javascript string对象方法总结
- 中海达手簿html测量报告,中海达GPS静态测量—内业解算导出报告(HGO静态解算软件教程)...
- 51单片机:stc烧录软件下载.hex文件遇到无法下载问题的解决方法(虚拟串口占用实际下载串口)
- 数字水印技术 概念 应用及现状
- C++多线程之_beginthread与_beginthreadex
- was英文读音_英语单词was怎么读
- 推出GitLab中国发行版GitLab JH
- 腾讯地图标注_在腾讯地图上标注店铺,只需要简单几步就搞定
- 牛客练习赛87 B k小数查询(STL)
- 三维视觉系统在顶盖激光焊接生产线上的应用案例
- PHP - Yii2编码规范/风格[PSR-1/PSR-2]
- 当人工智能遇上计算社会科学……