顺序存储结构,用一段地址连续的存储单元一次存储线性表的数据元素。比如数组
优点:
无需为表示表中元素之间的逻辑关系而增加额外的存储空间
可以快速的存取表中任意位置的元素,时间复杂度为O(1)
缺点:
插入和删除操作需要移动大量元素
当线性表成都变化较大时,难以确定存储空间的容量
造成存储空间的"碎片"
场景
适合数量固定,读取操作多,增删改少的场景。比如C#中的数组
package ***;
/**
* @Author: wsh
*/
public class ArrayTest {
public static void main(String[] args) {
DevArray devArray = new DevArray();
//init 19个数据
String data = "31,21,17,16,15,26,5,14,23,12,19,30,27,95,22,44,66,99,39";
devArray.init(data);
devArray.sout("初始化输出");
System.out.println("获取下标第4个"+devArray.getElement(4));
devArray.insertElement(3, 100);
devArray.sout("插入第3个后");
devArray.deleteElement(3);
devArray.sout("删除第3个后");
//测试首位插入
devArray.insertElement(0, 100);
devArray.sout("插入第0个后");
devArray.deleteElement(0);
devArray.sout("删除第0个后");
devArray.insertElement(devArray.length, 100);
devArray.sout("插入最后");
devArray.deleteElement(devArray.length);
devArray.sout("删除最后");
}
}
class DevArray{
private Integer MAXSIZE=20;
//数组类型存储
public int[] Element =new int[]{};
//数据的长度
//注:计算是含数据内容长度 不算初始化默认值的0
public int length;
/**
* 获取元素操作,返回L中第i的值
*/
int getElement(int i){
if (checkIndex(Element, i)) return -1;
return Element[i];
}
/**
* 插入
*
* 1.k等于内容长度的下标
* 2.依次从后往前挪
* 3.>= 包含要插入的位置,也要挪走
* 4.放入数据,长度+1
*
* 5.特殊1:插入0位 添加判断 k!=0
* 6.特殊2:插入末尾 直接插入(因方法第一行校验过了,长度足够)
*/
int insertElement( int insertIndex, int value) {
if (checkIndex(Element, insertIndex)||insertIndex+1>Element.length) {
System.out.println("插入校验失败,未成功");
return -1;
}
//插入末尾,不用移动
if(insertIndex != length + 1){
int k = length;
while (k >=insertIndex&&k!=0) {
Element[k] = Element[k - 1];
k--;
}
}
Element[insertIndex] = value;
length++;
return 0;
}
/**
* 删除
* 直接覆盖,以下标为起点依次左移,长度-1
*/
int deleteElement(int index) {
if (checkIndex(Element, index)) return -1;
int k = index;
while (k <length-1) {
Element[k] = Element[k+1];
k++;
}
length--;
return 0;
}
/**
* 校验长度
*/
boolean checkIndex(int[] L, int insertIndex) {
if (L.length == 0 || insertIndex < 0 || insertIndex > L.length){
System.out.println("====校验失败===");
return true;
}
return false;
}
/**
* 初始化 MAXSIZE - 1 个数据 乱序
*/
void init(String stringData) {
Element = new int[MAXSIZE];
String[] split = stringData.split(",");
for (int i = 0; i < split.length; i++) {
Element[i] =Integer.parseInt(split[i]);
}
length = split.length;
}
void sout(String str){
System.out.print(str+" ");
for (int i = 0; i < length; i++) {
//每5个间隔一下 好识别
if (i % 5 == 0) {
System.out.print(" ");
}
System.out.print(Element[i]+",");
}
System.out.println();
}
}
初始化输出 31,21,17,16,15, 26,5,14,23,12, 19,30,27,95,22, 44,66,99,39,
获取下标第4个15
插入第3个后 31,21,17,100,16, 15,26,5,14,23, 12,19,30,27,95, 22,44,66,99,39,
删除第3个后 31,21,17,16,15, 26,5,14,23,12, 19,30,27,95,22, 44,66,99,39,
插入第0个后 100,31,21,17,16, 15,26,5,14,23, 12,19,30,27,95, 22,44,66,99,39,
删除第0个后 31,21,17,16,15, 26,5,14,23,12, 19,30,27,95,22, 44,66,99,39,
插入最后 31,21,17,16,15, 26,5,14,23,12, 19,30,27,95,22, 44,66,99,39,100,
删除最后 31,21,17,16,15, 26,5,14,23,12, 19,30,27,95,22, 44,66,99,39,
收获,主要在边界处:
插入时特殊情况要考虑到
判断插入第一个时,向右平移,注意k-1 不能出现data[0-1] ===>>>data[-1]的情况,故加k!=0.
判断插入最后一个,平移略,在校验空间足够的情况下,直接插入即可.
同理,删除考虑向左平移,注意点最后面就可以
注意[k+1] 不大于 空间的长度,代码中是 k<长度-1 k<19 这样k=18时进入
例如空间长度10 ,其实最大下标就是9,故[k+1] < 空间长度