前面我们讲到线性表的顺序存储结构。最后的一段说明了他的缺点,最大的缺点就是插入和删除时需要移动大量的元素,有没有什么解决办法呢?
线性表的链式存储结构
线性表的链式存储是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的,这意味着,这些数据元素可以存在内存未被占用的任意位置。
以前的顺序结构中,每个元素只需要存储数据元素信息就可以了,现在链式结构中,除了存储元素信息外,还需要存储后继元素的存储地址。
因此,为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息
(即直接后继的存储位置)。我们把存储数据元素信息的域称为数据域,把存储直接后
继位置的域称为指针域。指针域中存储的信息称做指针或链。这两部分信息组成数据元素ai的存储映像,称为结点(Node)。
下面我们看代码实现:
Node代码实现:
public class Solution<T> {
Node<T> head;
int length;
static class Node<T> {
//存放下一个Node结点的地址
Node<T> next;
//存放当前Node结点的数据
T value;
public Node(T value) {
this.value = value;
}
public Node() {
}
}
}
单链表的元素读取
public T get(int index) {
if (index >= length){
throw new RuntimeException("error");
}
Node<T> temp = head;
while (index != 0) {
temp = temp.next;
index--;
}
return temp.value;
}
单链表的元素插入
public void add(T element) {
if (head == null) {
head = new Node<>(element);
length++;
return;
}
Node<T> temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = new Node<>(element);
length++;
}
public void add(T element, int index) {
if (index >= length){
add(element);
}
Node<T> node = new Node<>(element);
if (index == 0){
node.next = head;
head = node;
length++;
return;
}
Node<T> temp = head;
while (--index != 0){
temp = temp.next;
}
node.next = temp.next;
temp.next = node;
length++;
}
单链表的元素删除
public void remove(int index) {
if (index >= length){
throw new RuntimeException("error");
}
Node<T> temp = head;
if (index == 0){
head = temp.next;
temp.next = null;
length--;
return;
}
while (--index != 0){
temp = temp.next;
}
temp.next = temp.next.next;
length--;
}
链表打印信息方法
public void printMessage() {
Node<T> temp = head;
List<T> list = new ArrayList<>();
while (temp != null){
list.add(temp.value);
temp = temp.next;
}
System.out.println(Arrays.toString(list.toArray()));
}
测试类
class Test {
public static void main(String[] args) {
//实例化链表
Solution<Integer> solution = new Solution<>();
//插入元素
solution.add(1);
solution.add(2);
solution.add(3);
solution.add(4);
//信息打印
solution.printMessage();
//指定下标插入元素
solution.add(10,0);
//信息打印
System.out.println("=====插入了10后的结果打印");
solution.printMessage();
//元素获取
System.out.println("下标为4的元素为"+solution.get(4));
//删除头结点测试
solution.remove(0);
solution.remove(3);
//信息打印
System.out.println("删除了第一个和最后一个结点的信息为:");
solution.printMessage();
}
}
测试结果
总结一下链表的优缺点: