链表(LinkedList)介绍
链表是有序的列表,但是它在了内存中存储是按照下图存储的(物理结构)
链表有如下特点:
- 链表是以节点的方式来存储的
- 每个节点包括data域和next域:指向下一个节点;双向链表还包括prev域
- 如图:我们发现链表的各个节点不一定是连续存储的
- 链表分带头节点的链表和没有带头节点的链表,根据实际需求来确定
带头节点的单链接
单链表实现
public class SingleLinkedListDemo<E> {
private Node<E> head;
private int size = 0;
/**
* 尾插
*
* @param data 需要添加的元素
* @return 是否插入成功
*/
public boolean add(E data) {
linkLast(data);
return true;
}
/**
* 头插
*
* @param data 需要添加的元素
* @return 是否插入成功
*/
public boolean addFirst(E data) {
linkFirst(data);
return true;
}
/**
* 插入元素到链表末尾
*
* @param data 需要添加到链表的数据
*/
void linkLast(E data) {
if (head == null) {
this.head = new Node<>(data);
} else {
Node<E> temp = head;
while (temp.next != null) {
temp = temp.next;
}
temp.next = new Node<>(data);
}
size++;
}
/**
* 插入元素到链表头部
*
* @param data 需要添加到链表的数据
*/
void linkFirst(E data) {
Node<E> temp = this.head;
this.head = new Node<>(data);
head.next = temp;
size++;
}
void removeLast() {
if (head == null) {
throw new NullPointerException("链表为空");
}
Node<E> temp = head;
Node<E> target = temp.next;
while (temp.next != null) {
temp = target;
target = target.next;
}
temp.next = null;
size--;
}
void removeFirst() {
if (head == null) {
throw new NullPointerException("链表为空");
}
this.head = head.next;
size--;
}
void remove(E target) {
if (head == null) {
throw new NullPointerException("链表为空");
}
if (target == null) {
Node<E> temp = this.head;
Node<E> temp0 = temp.next;
while (temp.next != null) {
E data = temp0.data;
if (data == null) {
temp.next = temp0.next;
}
temp = temp0;
temp0 = temp0.next;
}
} else {
Node<E> temp = this.head;
Node<E> temp0 = temp.next;
while (temp.next != null) {
E data = temp0.data;
if (target.equals(data)) {
temp.next = temp0.next;
}
temp = temp0;
temp0 = temp0.next;
}
temp.next = null;
size--;
}
}
public int size() {
return size;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("SingleLinkedList{");
Node<E> temp = head;
while (temp != null) {
stringBuilder.append("[");
stringBuilder.append(temp.data);
stringBuilder.append("]");
if (temp.next != null) {
stringBuilder.append(", ");
}
temp = temp.next;
}
stringBuilder.append("}");
return stringBuilder.toString();
}
private static class Node<E> {
private Node<E> next;
E data;
public Node(E data) {
this.data = data;
}
@Override
public String toString() {
return "Node{" +
"data=" + data +
'}';
}
}
}