1.链表
在计算机科学中,链表示数据元素的线性集合,每个元素都指向下一个元素,元素存储上并不连续;
2.分类
单链表:存储数据的节点只有一个指针域指向下一个节点的地址;
双向链表:存储数据的节点有两个指针域,一个用来指向其前驱结点的地址,一个用来指向其·后继节点的地址;
循环链表:通常的链表尾结点tail指向的都是null,而循环链表的tail指向的是头结点head;
~在链表中还有一种特殊的节点称为哨兵节点,也叫哑元结点,其不存储数据,通常用作头尾,用来简化边界判断;(巧妙利用头结点可以使一些操作变得简单)
3.性能
随机访问:根据index查找,时间复杂度O(1);
插入或删除:起始位置:O(1);
结束位置:如果已知tail尾结点是O(1),不知道tail尾结点是O(n);
中间位置:根据index查找时间+O(1);
4.基本操作代码
①类和方法设计
import java.util.Iterator;
import java.util.function.Consumer;
public class SinglyLinkedlist implements Iterable<Integer>{
private Node Head=null; //头指针
private static class Node{ //创建节点
int date; //数据域
Node next; //指针域
public Node(int date,Node next){
this.date=date;
this.next=next;
}
}
//头插法
public void addFirst(int date){ //在头部添加元素
//1.若链表为空
//Head=new Node(date,null);
//2.链表不为空
Head=new Node(date,Head);
}
//遍历链表
public void foreach(Consumer<Integer> consumer){
Node p=Head;
while(p!=null){
consumer.accept(p.date);
p=p.next;
}
}
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.date;
p=p.next;
return v;
}
};
}
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 date){ //末尾添加元素
Node p=findLast();
if(p==null){
addFirst(date);
return;
}
p.next=new Node(date,null);
}
private Node findindex(int index){ //查找元素索引
int i=0;
for(Node p=Head;p!=null;p=p.next,i++){
if(i==index){
return p;
}
}
return null;
}
public int finddate(int index){ //根据索引找结点值
Node x=findindex(index);
if(x==null){
throw new IllegalArgumentException(String.format
("index [%d] 不合法!%n",index));
}
return x.date;
}
public void insert(int index,int date){ //在任意位置添加元素
if(index==0){
addFirst(date);
return;
}
Node node=findindex(index-1);
if(node==null){
throw new IllegalArgumentException(String.format
("index [%d] 不合法!%n",index));
}
node.next=new Node(date,node.next);
}
public void removeHead(){ //头部删除
if(Head==null){
throw new IllegalArgumentException(String.format("index [0]不合法%n"));
}
Head=Head.next;
}
public void remove(int index){ //任意位置删除
if(index==0){
removeHead();
return;
}
Node node=findindex(index-1);
Node remove=node.next;
if(node==null||remove.next==null){
throw new IllegalArgumentException(String.format
("index [%d] 不合法!%n",index));
}
node.next=node.next.next;
}
}
②测试代码
public class test {
public static void main(String[] args) {
SinglyLinkedlist linkedlist=new SinglyLinkedlist();
//linkedlist.addFirst(5);
//linkedlist.addFirst(6);
//linkedlist.addFirst(7);
//linkedlist.foreach(date-> System.out.println(date));
//for (Integer date : linkedlist) {
// System.out.println(date);
// }
linkedlist.addLast(8);
linkedlist.addLast(9);
linkedlist.addLast(10);
linkedlist.addLast(11);
//linkedlist.insert(3,5);
linkedlist.remove(0);
linkedlist.foreach(date-> System.out.println(date));
}
}