到目前为止,线性表的顺序存储、链式存储的基础概念已经讲完了。积攒了那么多的专业词汇,就欠东风了。接下来就是"顺序存储"的实战。
在"顺序存储"一章中,提到了插入、删除、查询、长度等都是必备操作。今天也是主要围绕着这几个功能去进行一个简单的编写,通过数组来实现数据结构。话不多说,上菜。
/**
* 顺序存储-数组
* 需要的一些功能:添加、删除、查找、长度等等
*/
public class TestArray {
/**
* 初始化好需要的参数
* 1、存放数组 DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* 2、数组长度 elementSize
* 3、数组初始化长度 length
*/
private static int[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
private int elementSize;
private int length;
/**
* 通过构造方法来创建一个长度默认是10的数组
*/
public TestArray() {
elementSize = 0;
length = 10;
DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new int[length];
}
public TestArray(int length) {
elementSize = 0;
this.length = length;
DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new int[length];
}
/**
* 获取长度
*
* @return
*/
public int size() {
return elementSize;
}
/**
* 数组是否为空
*
* @return
*/
public boolean isEmpty() {
return elementSize == 0;
}
/**
* 添加
*/
public boolean add(int e) {
//添加元素超过当前默认大小,或者指定大小的话,添加失败
if (elementSize == length) {
return false;
} else {
DEFAULTCAPACITY_EMPTY_ELEMENTDATA[elementSize++] = e;
return true;
}
}
/**
* 根据下标查找,触发下标越界
*/
public int get(int index) {
if (index >= elementSize)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
return DEFAULTCAPACITY_EMPTY_ELEMENTDATA[index];
}
/**
* 根据元素查找对应下标,无此元素返回-1
*/
public int indexOf(int e) {
for (int i = 0; i < elementSize; i++) {
if (e == DEFAULTCAPACITY_EMPTY_ELEMENTDATA[i]) {
return i;
}
}
return -1;
}
/**
* 根据元素进行移除
*/
public boolean remove(int e) {
int index = indexOf(e);
if (index == -1) {
return false;
} else {
//最后一位的话。长度改变即可
if (index == elementSize - 1) {
elementSize--;
} else {
for (int i = index; i < elementSize - 1; i++) {
//删除中间元素的话,从当前删除坐标后的元素,依次向前一位进行移动。ArrayList 则是通过System.arraycopy()进行一个元素的前移。
DEFAULTCAPACITY_EMPTY_ELEMENTDATA[i] = DEFAULTCAPACITY_EMPTY_ELEMENTDATA[i + 1];
}
elementSize--;
}
return true;
}
}
/**
* 更新对应坐标的值
*
* @param index
* @param element
*/
public void update(int index, int element) {
if (index > elementSize || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
DEFAULTCAPACITY_EMPTY_ELEMENTDATA[index] = element;
}
/**
* 错误信息返回
*
* @param index
* @return
*/
private String outOfBoundsMsg(int index) {
return "Index: " + index + ", Size: " + elementSize;
}
}
StringBuilder stringBuilder = new StringBuilder();
TestArray testArray = new TestArray();
// 1、添加
testArray.add(1);
testArray.add(2);
testArray.add(3);
testArray.add(4);
// 2、长度
testArray.size();
// 3、是否为空
testArray.isEmpty();
// 4、根据元素获取下标
int indexOf = testArray.indexOf(4);
// 5、根据下标获取元素
int element = testArray.get(0);
// 6、根据下标更新元素
testArray.update(0, 2);
stringBuilder.append("\nsize--")
.append(testArray.size())
.append("\nisEmpty--")
.append(testArray.isEmpty() ? 0 : 1)
.append("\nindexOf--")
.append(indexOf)
.append("\nelement--")
.append(element)
.append("\nupdateElement--")
.append(testArray.get(0));
Log.d("TestArray", stringBuilder.toString());
打印:
TestArray: size--4 添加后一共有4个元素
isEmpty--1 数据长度不为空
indexOf--3 元素4下标索引为3
element--1 第一个元素为1
updateElement--2 已将第一个值改为元素2
总结:
上面通过"数组"实现了一个简单的顺序存储,当然这里面也存在着许多问题。但主要目的还是为了巩固日常开发中常用的数据结构—“数组”,数组的优缺点已经在前面两章中讲过,这里再进行一次巩固:
顺序存储优点:查询快、效率高、有序
顺序存储缺点:增删慢、容易造成存储空间碎片、线性表长度过大时,难以确定存储空间容量。
不同的数据结构在不同的方面有着不同的性能与效率,下篇进行实战"链式存储"。