1. 什么是线性表的链式存储
前面我们看过线性表的顺序存储结构,他是通过数组开辟一段连续的地址空间来实现的,在做插入操作和删除操作时,因为要维护数组的结构所以时间复杂度为O(N);有什么办法可以解决删除和插入操作效率低的办法吗?没错就是链表,我们只需要在保存当前数据的同时,也保存其下一个元素的地址就行了,这样在删除和修改时实际上并不需要维护结构,只需要改变被删除或被插入数据上一个的地址指向和下一个的地址指向即可。
原使用顺序存储时的结构如下。
使用链表存储时的结构如下。
2. 优缺点
通过上图可以看出在插入数据或删除数据时效率明显高于顺序存储结构,但是你可能发现了在查找时链式存储结构效率是低于顺序存储结构的,原因是在查找时必须遍历链表依次去拿下一个的地址值才能找到对应的数据。所有在插入数据和删除数据时链式存储结构效率高于顺序存储结构而查找低于顺序存储结构,在Java中我们都知道ArrayList是基于数组的,而LinkedList基于链表,所以在查找比较多的时候我们应该使用ArrayList,而插入和删除比较多的时候应该使用LikedList。
3. 使用Java代码实现链式存储
package com.bigcat;
/** * 单向链表,实现新增,插入,获取,删除操作 * @author damao * @date 2019/11/12 */public class MyLinkedList<T>{
private static Node PREV_ADDRESS = null;
private Node<T> firstNode;
private static int size = 0;
public Boolean add(T t){ if (PREV_ADDRESS == null) { PREV_ADDRESS = firstNode = new Node(null,t); }else{ Node<T> node = new Node(null, t); PREV_ADDRESS = PREV_ADDRESS.next = node; } size++; return true; }
public Boolean add(int index,T t){ if(index <= 0){ throw new RuntimeException("Index must be greater than zero"); } if(index == 1){ firstNode = new Node(firstNode.next,t); return true; } Node<T> prev = null; Node<T> theNode = firstNode; for (int i = 1; i <= index; i++) { if(index == i){ Node<T> node = new Node(theNode,t); prev.next = node; return true; } prev = theNode; theNode = theNode.next; } return true; }
public T get(int index){ if(index <= 0){ throw new RuntimeException("Index must be greater than zero"); } if(index > size){ throw new RuntimeException("Exceeded maximum index stored"); } Node<T> theNode = firstNode; for (int i = 1; i <= index; i++) { if(index == i){ return theNode.value; } theNode = theNode.next; } return null; }
public Boolean remove(int index){ if(index <= 0){ throw new RuntimeException("Index must be greater than zero"); } if(index > size){ throw new RuntimeException("Exceeded maximum index stored"); } if(index == 1){ firstNode = firstNode.next; return true; } Node<T> prev = null; Node<T> theNode = firstNode; for (int i = 1; i <= index; i++) { if(index == i){ prev.next = theNode.next; theNode.next = null; return true; } prev = theNode; theNode = theNode.next; } return false; }
private static class Node<T>{ Node<T> next; T value; public Node(Node<T> next, T value) { this.next = next; this.value = value; } }
}
测试结果如下