线性表
- 线性表是最基本,最简单最常用的一种数据结构,可以理解为我们高数中所学的数列,一个线性表是n个具有相同特性的数据元素组成的有限序列。
- 前驱元素:若a元素在b元素的前面,则称a为b的前驱元素。
- 后继元素:若a元素在b元素的后面,则称a为b的后继元素。
特征
- 1.第一个数据没有前驱元素,称为头节点。
- 2.末尾元素没有后继元素,称为尾节点。
分类
线性表中数据的存储方式可以是顺序存储,也可以是链式存储。按照存储方式不同分为顺序表和链表。
顺序表
- 顺序表是在计算机内存中以数组形式保存的线性表,顺序存储是指一组地址连续的存储单元,依次存储线性表中的各个元素,所以我们实现顺序表是基于数组实现的。
代码实现
- 实现代码
public class SequenceList<T> {
//1.存储元素的数组
private T[] array;
//2.当前线性表的长度
private int n;
//capacity n.容量
public SequenceList(int capacity) {
//1.初始化数组
this.array = (T[]) new Object[capacity];
//2.初始化长度
this.n = 0;
}
//1.置空
public void clean() {this.n = 0;}
//2.判空
public boolean isEmpty() {return n == 0;}
//3.线性表的长度
public int length() {return n;}
//4.返回指定索引处的元素的值
public T get(int i) {return array[i];}
//5.在i之前插入值为t的元素
public void insert(int i,T t) {
//先将i索引处及其后面的元素依次向后移动一位
for (int index = n-1; index > i ; index--) {
array[index] = array[index-1];
}
//再将t放置i索引处
array[i] = t;
}
//6.添加元素(末尾)
public void insert(T t) {
array[n++] = t;//先给索引0处赋值,然后再自增
}
//7.删除并返回删除的元素
public T remove(int i) {
//记录i处的值
T current = array[i];
//i后的元素依次前移
for (int j = i; j < n-1; j++) {
array[j] = array[j+1];
}
//元素个数-1
n--;
return current;
}
//8.返回首次出现元素的位置,不存在返回-1
public int indexOf(T t) {
for (int i = 0; i < n; i++) {
if (array[i].equals(t)) {
return i;
}
}
return -1;
}
}
- 测试代码
public class SequenceListTest {
public static void main(String[] args) {
//create
SequenceList list = new SequenceList(10);
//insert
list.insert("0");
list.insert("0");
list.insert("8");
list.insert("2");
list.insert("8");
list.insert(0,"1999");
//check
System.out.println(list.get(0));
//delete
Object remove = list.remove(1);
System.out.println(remove);
}
}
容量可变
那我们呢再深入的考虑一个问题,我们在初始化顺序表的时候,是设置了它的大小的,换言之,顺序表的大小是不可变的,那我们在对其进行添加操作时,当添加满之后呢?
很显然,程序一定会报错(索引越界异常),因此在设计顺序表时,一定要考虑它的可伸缩性(扩容)。也就是说,在添加元素时,我们要进行适当的扩容,在移除元素是
需要进行适当的缩容(内存空间浪费)。
- 代码实现
//根据参数newSize来重置array大小
public void controlSize(int newSize) {
//1.create a temporary array
T[] temp = array;
//2.create a new array
array = (T[])new Object[newSize];
//3.copy
for (int i = 0; i < n; i++) {
array[i] = temp[i];
}
}
//5.在i处插入值为t的元素
public void insert(int i,T t) {
if (n == array.length) {
controlSize(2*array.length);
}
//先将i索引处及其后面的元素依次向后移动一位
for (int index = n; index > i ; index--) {
array[index] = array[index-1];
}
//再将t放置i索引处
array[i] = t;
//元素个数+1
n++;
}
时间复杂度
- 查询某个元素的时间复杂度为O(1)。
- 插入时,元素要进行后移(for循环),所以时间复杂度为O(n),同理删除也是。