定义:在计算机科学中,链表是数据元素的线性集合,其每个元素都指向下一个元素,元素存储上并不连续。
链表分类:单向链表(每个元素知道下一个元素是谁)、双向链表(每个元素知道其上一个元素和下一个元素)、循环链表(通常链表尾结点tail指向的都是null,而循环链表的tail指向的是头结点head)。
链表中还有一种特殊的节点称为哨兵结点,也叫作哑元节点,它不存储数据,通常用作头尾,用来简化边界判断。
性能
随机访问:根据index查找,时间复杂度O(n)
插入或删除
起始位置:O(1)
结束位置:如果一直tail尾节点是O(1),不知道tail尾节点是O(n)
中间位置:根据index查找时间+O(1)
初始化链表
java
private Node head=null;//头指针
/*
节点类(内部实现)
链表由多个节点组成,所以他们是组合关系
*/
public static class Node{
int value;//值
Node next; //下一个节点指针
public Node(int value, Node next){
this.value=value;
this.next=next;
}
}
添加元素
java
public void addFirst(int value){
//1.链表为空
// head =new Node(value,null);
//2.链表非空
head =new Node(value,head);//既能处理链表为空或者链表非空的情况。
}
遍历链表
java
public void loop(Consumer<Integer> consumer){
Node p=head;
while(p!=null){
// System.out.println(p.value);
consumer.accept(p.value);
p=p.next;
}
}
测试类中遍历时的代码

java
//使用for循环遍历
public void loop1(Consumer<Integer> consumer){
for (Node p=head; p!=null;p=p.next){
consumer.accept(p.value);
}
}
java
//迭代器遍历
import java.util.Iterator;
import java.util.function.Consumer;
public class SinglyLinkedList implements Iterable<Integer>{//整体
private Node head=null;//头指针
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>(){
Node p=head;
@Override
public boolean hasNext() {//是否有下一个元素
return p!=null;
}
@Override
public Integer next() {// 返回当前值,并指向下一个元素
int v=p.value;
p=p.next;
return v;
}
};
}
迭代器遍历测试类形式:

静态只能调静态,非静态可以调所有。
addLast()
java
private Node findLast(){
if(head==null){//空链表
return null;
}
Node p;
for(p = head ; p.next != null ; p = p.next){
}
return p;
}
public void addLast(int value){
Node last=findLast();
if (last==null){
addFirst(value);
return;
}
last.next=new Node(value,null);
}
检验:

打印索引:
java
//索引
public void test(){
int i=0;
for(Node p=head;p!=null;p=p.next,i++){
System.out.println(p.value+"索引是:"+i);
}
}
java
public Node findNode(int index){
int i=0;
for(Node p=head;p!=null;p=p.next,i++){
if(i==index){
return p;
}
}
return null;//没有找到的情况下
}
public int get(int index){
Node node=findNode(index);
if(node==null){
throw new IllegalArgumentException(
String.format("index[%d] 不合法%n",index));
}
return node.value;
}
往链表内添加一个元素。
java
//向索引位置插入
public void insert(int index,int value){
Node prev=findNode(index-1);//上一个节点
if(index==0){
addFirst(value);
return;
}
if(prev==null){//找不到
throw illegalIndex(index);
}
prev.next=new Node(value,prev.next);
}
private static IllegalArgumentException illegalIndex(int index) {
return new IllegalArgumentException(//抛出一个异常
String.format("index[%d] 不合法%n", index));
}
java
//按索引删除
public void remove(int index){
Node prev=findNode(index-1);//上一个节点
if(prev==null){
throw illegalIndex(index);
}
Node removed=prev.next;//被删除的结点
if(removed==null){
throw illegalIndex(index);
}
prev.next=removed.next;
}