1. ArrayList的缺陷
由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。因此:java集合中又引入了LinkedList,即链表结构。
2. 链表
2.1 链表的概念及结构
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
- 单向或者双向
- 带头或者不带头
- 循环或者非循环
虽然有这么多的链表的结构,但是我们重点掌握两种:
- 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
- 无头双向链表:在Java的集合框架库中LinkedList底层实现就是无头双向循环链表。
2.2 链表的实现
public class SingleLinkedList {
static class ListNode {
public ListNode next;
public int val;
public ListNode(int val) {
this.val = val;
}
}
public ListNode head;
public void createList() {
ListNode node1 = new ListNode(12);
ListNode node2 = new ListNode(23);
ListNode node3 = new ListNode(34);
ListNode node4 = new ListNode(45);
ListNode node5 = new ListNode(56);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
this.head = node1;
}
public void addFirst(int data){
ListNode listNode = new ListNode(data);
listNode.next = head;
head = listNode;
}
//尾插法
public void addLast(int data){
ListNode listNode = new ListNode(data);
ListNode cur = head;
if (cur == null) {
head = listNode;
return;
}
while (cur.next != null) {
cur = cur.next;
}
cur.next = listNode;
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data){
ListNode listNode = new ListNode(data);
if (index < 0 || index > size()) {
System.out.println("index位置不合法");
return;
}
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
ListNode cur = findIndexSubOne(index);
listNode.next = cur.next;
cur.next = listNode;
}
private ListNode findIndexSubOne(int index) {
ListNode cur = head;
for (int i = 0; i < index-1; i++) {
cur = cur.next;
}
return cur;
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key){
ListNode cur = head;
while (cur != null) {
if (cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int key){
ListNode cur = head;
if (cur.val == key) {
head = cur.next;
return;
}
while (cur.next != null) {
if (cur.next.val == key) {
cur.next = cur.next.next;
return;
}
cur = cur.next;
}
}
//删除所有值为key的节点
public void removeAllKey(int key){
if (head == null) {
return;
}
ListNode prev = head;
ListNode cur = head.next;
while (cur != null) {
if (cur.val == key) {
prev.next = cur.next;
} else {
prev = cur;
}
cur = cur.next;
}
if (head.val == key) {
head = head.next;
}
}
//得到单链表的长度
public int size(){
int sz = 0;
ListNode cur = head;
while (cur != null) {
sz++;
cur = cur.next;
}
return sz;
}
public void clear() {
ListNode cur = head;
while (cur != null) {
ListNode curN = cur.next;
cur.next = null;
cur = curN;
}
head = null;
}
public void display() {
ListNode cur = head;
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
}
public class Test {
public static void main(String[] args) {
SingleLinkedList singleLinkedList = new SingleLinkedList();
singleLinkedList.createList();
singleLinkedList.display();
singleLinkedList.addFirst(10);
singleLinkedList.display();
singleLinkedList.addLast(67);
singleLinkedList.display();
System.out.println(singleLinkedList.size());
singleLinkedList.addIndex(0, 9);
singleLinkedList.display();
singleLinkedList.addIndex(8, 78);
singleLinkedList.display();
singleLinkedList.addIndex(2, 11);
singleLinkedList.display();
singleLinkedList.addIndex(-1, 11);
System.out.println(singleLinkedList.contains(78));
System.out.println(singleLinkedList.contains(9));
System.out.println(singleLinkedList.contains(34));
System.out.println(singleLinkedList.contains(99));
singleLinkedList.remove(23);
singleLinkedList.display();
singleLinkedList.remove(78);
singleLinkedList.display();
singleLinkedList.remove(9);
singleLinkedList.display();
singleLinkedList.addLast(10);
singleLinkedList.addLast(10);
singleLinkedList.addLast(10);
singleLinkedList.addLast(10);
singleLinkedList.display();
singleLinkedList.removeAllKey(10);
singleLinkedList.display();
singleLinkedList.clear();
singleLinkedList.display();
}
}
执行结果
12 23 34 45 56
10 12 23 34 45 56
10 12 23 34 45 56 67
7
9 10 12 23 34 45 56 67
9 10 12 23 34 45 56 67 78
9 10 11 12 23 34 45 56 67 78
index位置不合法
true
true
true
false
9 10 11 12 34 45 56 67 78
9 10 11 12 34 45 56 67
10 11 12 34 45 56 67
10 11 12 34 45 56 67 10 10 10 10
11 12 34 45 56 67