前言
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接顺序实现的。
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表的插入的事件复杂度是O(N),查找的事件复杂度是O(1);
主要实现
public class SingleLinkedList<T> {
//头结点
private Node<T> header;
public SingleLinkedList() {
}
public void insert(T[] arr) {
for (T t : arr) {
insertLast(t);
}
}
public void insertLast(T item) {
if (isEmpty()) {
header = new Node<T>(item);
return;
}
Node<T> node = header;
while (node.next != null) {
node = node.next;
}
Node<T> newNode = new Node<>(item);
node.setNext(newNode);
}
public void insertFirst(T item) {
if (isEmpty()) {
header = new Node<>(item);
return;
}
Node<T> newNode = new Node<>(item);
Node<T> tem = header;
header = newNode;
header.setNext(tem);
}
public Node<T> remove(T item) {
if (isEmpty()) {
return null;
}
Node<T> node = header;
if (node.item == item) {
return deleteHeaderNode();
} else {
//找到要删除节点的上一个节点;
while (node.next != null) {
if (item.equals(node.next.item)) {
break;
}
node = node.next;
}
Node<T> delNode = node.next;
if (delNode != null) {
node.setNext(delNode.next);
return delNode;
}
}
return null;
}
//删除头结点
private Node<T> deleteHeaderNode() {
Node<T> deleteNode = header;
if (deleteNode.next == null) {
header = null;
} else {
header = deleteNode.next;
}
return deleteNode;
}
public boolean isEmpty() {
return header == null;
}
/**
* 反转单链表
* 反转 1-2-3-4-5-6
* 6-5-4-3-2-1
*/
public void reversal() {
Node node = header;
reversal(node);
}
/**
* 遍历法
* 反转链表:将当前节点(curNode)和上一个节点(preNode)记录下来,让curNode的next指向preNode;
* 重新为header节点赋值;
*
* @param node
*/
public void reversal(Node<T> node) {
Node<T> preNode = null;
Node<T> curNode = node;
while (curNode != null) {
Node<T> next = curNode.next;
curNode.setNext(preNode);
//保存上一个节点和当前节点
preNode = curNode;
curNode = next;
}
//重新赋值header节点
header = preNode;
}
public void traversal() {
if (isEmpty()) {
return;
}
Node<T> node = header;
StringBuilder stringBuilder = new StringBuilder();
while (node != null) {
stringBuilder.append(node.item).append(" ");
node = node.next;
}
Logger.e(stringBuilder.toString());
}
static class Node<T> {
private T item;
private Node<T> next;
public Node(T item) {
this.item = item;
}
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
}
}
以上就是单链表的主要操作,如有问题,请多指教,谢谢!