目录
1. 顺序表
1.1 顺序及结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
1.2 代码框架
public class SeqList {
// 打印顺序表
public void display() { }
// 在 pos 位置新增元素
public void add(int pos, int data) { }
// 判定是否包含某个元素
public boolean contains(int toFind) { return true; }
// 查找某个元素对应的位置
public int search(int toFind) { return -1; }
// 获取 pos 位置的元素
public int getPos(int pos) { return -1; }
// 给 pos 位置的元素设为 value
public void setPos(int pos, int value) { }
//删除第一次出现的关键字key
public void remove(int toRemove) { }
// 获取顺序表长度
public int size() { return 0; }
// 清空顺序表
public void clear() { }
}
1.3 具体代码
1.3.1 创建类
public class MyArrayList {
//属性
private int[] elem;
private int usedSize;
private final int CAPACITY = 10;
public MyArrayList() {
this.elem = new int[CAPACITY];
this.usedSize = 0;
}
需要定义一些属性来实现顺序表存储:
elem为一个存顺序表的数组。
usedSize来定义有效元素个数。
CAPACITY定义数组初始容量。
1.3.2 打印顺序表
即实现一个类似toString的方法来打印写好的顺序表。
代码如下
public void display() {
System.out.print("[");
for (int i = 0; i < usedSize; i++) {
System.out.print(this.elem[i]);
if (i != usedSize - 1) {
System.out.print(", ");
}
}
System.out.println("]");
}
1.3.3 新增元素
代码如下
public void add(int pos, int data) {
if (pos < 0 || pos > usedSize) {
return;
}
if (usedSize >= this.elem.length) {
realloc();
}
if (usedSize == pos) {
this.elem[pos] = data;
this.usedSize++;
} else {
for (int i = usedSize; i > pos; i--) {
this.elem[i] = this.elem[i - 1];
}
this.elem[pos] = data;
this.usedSize++;
}
}
在新增元素过程中可能导致元素过多容量不够的情况,故因写一个扩容方法解决。
代码如下
private void realloc() {
int[] newElem = new int[this.elem.length * 2];
for (int i = 0; i < this.elem.length; i++) {
newElem[i] = this.elem[i];
}
this.elem = newElem;
}
1.3.4 判定是否包含某个元素
代码如下
public boolean contains(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if (toFind == this.elem[i]) {
return true;
}
}
return false;
}
1.3.5 查找到元素位置
代码如下
public int search(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if (toFind == this.elem[i]) {
return i;
}
}
return -1;
}
1.3.6 获取pos位置的元素
代码如下
public int getPos(int pos) {
if (pos < usedSize && pos >= 0) {
return this.elem[pos];
}
return -1;
}
1.3.7 删除第一次出现的关键字key
代码如下
public void remove(int toRemove) {
int pos = search(toRemove);
if (pos == -1) {
return;
}
if (pos == usedSize - 1) {
this.usedSize--;
return;
}
for (int i = pos; i < usedSize - 1; i++) {
this.elem[i] = this.elem[i + 1];
}
this.usedSize--;
}
1.3.8 其他
// 获取顺序表长度
public int size() {
return this.usedSize;
}
// 清空顺序表
public void clear() {
this.usedSize = 0;
this.elem = new int[CAPACITY];
}
1.4 顺序表的问题与思考
1. 顺序表中间/头部的插入删除,时间复杂度为O(N)
2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。
所以引入链表来解决。