数据结构与算法(二):线性表之数组
2018-09-12 17:09
183 查看
版权声明:转载请注明 https://blog.csdn.net/doraemon7/article/details/82663297
一、线性表的定义
线性表
零个或多个元素的有限序列
需要强调两点:
第一,线性表是一个序列,也就是说,元素之间是有顺序的
第二,线性表是有限的,即元素的个数是有限制的。当线性表中的元素个数(n = 0)时,线性表为空,称为空表
二、线性表的基本操作
// 初始化一个空的线性表 void init(); // 获取线性表中元素的个数 int getSize(); // 判断线性表是否为空表 boolean isEmpty(); // 插入一个元素 void add(E e); // 删除一个元素 E remove(E e); // 查找元素e是否存在与线性表中 boolean contains(E e);
数组 - 线性表的顺序存储结构
线性表的顺序存储结构,指用一段连续的存储单元依次存储线性表的数据元素。
线性表的存储示意图如下:
摘自《大话数据结构》
接着来看看Java中自定义数组的初始化代码:
public class Array<E> { private E[] data; private int size; /** * 设置初始容量 */ public Array(){ this(10); } public Array(int capacity){ this.data = (E[]) new Object[capacity]; size = 0; } }
从以上代码,我们可以看出,顺序存储需要的三个属性:
存储空间的起始位置: 数组 data,它的存储位置就是存储空间的存储位置
线性表的最大存储容量: capacity
线性表的当前长度: size
地址计算方式
数组的下标从0开始,如果要访问数组的第i个元素,其下标应为 i - 1
摘自《大话数据结构》
获取数组中的一个元素
// 时间复杂度 T = O(1) public E get(int index){ if(index < 0 || index >= size){ throw new IllegalArgumentException("Get failed.ArrayIndexOutOfBounds."); } return data[index]; }
向数组中插入元素
插入元素时,需要将该元素将要插入位置的元素及后面的元素全部后移一个存储单元,如图所示:
摘自《大话数据结构》
插入算法的思路:
如果插入位置不合理,则抛出异常
如果插入元素之后数组的长度大于等于数组的容量,那么进行扩容,或者抛出异常
从最后一个元素向前开始遍历到index,将这些位置上的元素都向后移动一个位置
将要插入的元素插入到index
维护size,size 加 1
代码实现如下:
/** * 时间复杂度 T = O(n) */ public void add(int index,E e){ if(index < 0 || index > data.length){ throw new IllegalArgumentException("Add failed. Index might only between 0 to capacity."); } if(size == data.length){ resize(data.length * 2); } for(int i = size - 1;i >= index;i--){ // 将插入位置的后面的元素后移 data[i + 1] = data[i]; } data[index] = e; size ++; }
删除数组中的元素
摘自《大话数据结构》
删除算法的思路:
如果删除位置不合理,则抛出异常
取出删除元素
从要删除元素的 index 位置开始遍历到最后一个元素,将这些元素都向前移动一个位置
维护size, size 减 1
代码实现如下:
// 时间复杂度 T = O(n) public E remove(int index){ if(index < 0 || index >= size){ throw new IllegalArgumentException("Remove failed. Index might only between 0 to capacity."); } E ret = data[index]; for(int i = index + 1;i < size;i++){ data[i - 1] = data[i]; } size --; data[size] = null; // 防止复杂度震荡 if(size == data.length / 4 && data.length / 2 != 0){ resize(data.length / 2); } return ret; }
查找数组中的元素
/** * T = O(n) */ public int find(E e){ for(int i = 0;i < size;i++){ if(data[i].equals(e)){ return i; } } return -1; }
总结
数组的优点
- 可以快速查找数组中的任一元素
数组的缺点
如果插入和删除不在尾部,那么这些操作都需要移动大量的元素,效率较低
当数组长度变化较大时,难以确定数组的存储空间的容量,会导致存储空间的浪费,造成存储空间的 ” 碎片 “
相关文章推荐
- 8. C#数据结构与算法 -- 线性存储结构(线性表之顺序表,数组实现)
- 面试准备--数据结构与算法(一)--线性结构--数组、单链表、双链表
- 数据结构与算法系列-线性表-数组(线性表的推广)
- 1.数据结构--线性表之数组实现
- 在数组A中寻找第k小的元素-最坏情况为线性时间的算法
- 基于数组的顺序线性表的实现
- 最大子数组问题的递归和非递归(线性时间)代码
- 用线性时间复杂度实现找出数组中出现一次的元素
- 线性表的数组描述
- 【算法】_014_最大子数组_线性法
- 数据结构之线性结构--数组
- 数据结构线性存储之连续存储数组的实现
- 数据结构 线性结构中的数组
- java数据结构与算法-有序数组二分查找
- 6维数组下标到1维线性内存地址的相互映射
- 线性结构---连续存储[数组]
- 数据结构学习笔记(3.线性表之静态链表及柔性数组)
- 线性表的清空与线性表的销毁有什么区别 静态链表与数组的区别
- 线性表-数组和链表的区别与联系
- 线性表——数组描述(Qt5.1测试代码 for windows)