自定义顺序表
目录
一、包含功能
-
插入元素
1.尾插
2.中间指定位置插入 -
删除元素
1.按照下标位置删除 2.按照元素删除
-
获取元素
-
修改元素
-
判断元素是否存在
-
查找元素位置
1. 从前往后 2. 从后往前
-
清空元素
-
求长度
-
判断是否为空
二、具体实现过程
0.0 自定义顺序表
此处非泛型版本,默认 ArrayList 中存在的是若干的 String.
public class MyArrayList {
//属性
private String[] data = null;
//因为此处的数组为空,不可以直接对其插入元素,
// 会导致空指针引用,因此需要一个构造方法初始化
private int size = 0; //当前顺序表中的有效元素个数
//当前顺序表中的最大元素容纳个数,若 size 超过了 capacity,则需要扩容
private int capacity = 100;
//因为数组 data 为空,不可以直接对其插入元素,会导致空指针引用,因此需要一个构造方法初始化
public MyArrayList(){
data = new String[capacity];
}
...
0.1 扩容
在实现过程中,若遇到顺序表元素超出了顺序表容量,则需要先对顺序表进行扩容,
此处自定义扩容函数函数 realloc()
private void realloc(){
//先把 capacity 扩大,具体扩大的公式,可以任意选择
capacity = 2 * capacity;
String[] newData = new String[capacity];
//把旧数组中的数据拷贝到新数组中
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
//把新的大的数组赋值给原有的属性 data,同时就会释放旧的数组(GC)
data = newData;
}
0.2 重写toString
java中若不重写 toString 则输出的是对象的hash码
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("顺序表中存的数据是:[");
for (int i = 0; i < size; i++) {
stringBuilder.append(data[i]);
if(i < size-1){
stringBuilder.append(",");
}
}
stringBuilder.append("]");
return stringBuilder.toString();
}
- 直接使用 return Arrays.toString(data)-----不可以直接使用该语句,原因是 capacity 和 size 不相等,此语法相当于直接打印了 capacity.
1.插入元素
1.1 尾插
实现思路:
尾插的思想是在顺序表尾部直接添加目标元素即可,因为当前顺序表中最后一个元素的下标
是size-1.
public void add(String elem){
if(size >= capacity){
//先扩容
realloc(); //时间复杂度是O(N)
}
data[size] = elem; //把新元素放到下标为 size 的位置上即可
size++; //时间复杂度是O(1)
}
//尾插的时间复杂度是O(N) + O(1),最终是O(N)
//扩容操作时小概率事件,一般情况下其平均复杂度视为O(1)
- 扩容过程中的计算方式,可以采用正常的算术运算符中的任意一种对其进行扩大
- 扩容过程中需要遍历整个顺序表,故其时间复杂度为O(N).
1.2 指定位置插入
实现思路:
考虑到对目标位置插入新的元素会将目标位置旧元素覆盖掉,因此现需要对目标位置以后的元素
整体向后移动一个位置,为目标位置腾出一个空位置用来存放目标元素.
public void add(int index,String elem){
//如果 index == size,相当于把新元素插入到末尾
if(index < 0