链表结构

链表

一、链表的分类

1.1 单项链表

每个node节点指向下一个节点。然后有个head节点指向第一个节点,尾节点指向null。也可以有个last节点指向最后一个节点。这样能快速获取最后一个节点,再增加节点的时候能提升效率。

 

 

 

1.2 双向链表

每个节点都有一个pre变量存储上一个节点的地址,一个next变量存储下下一个节点的地址。最后一个节点的next存储null

 

 

 

1.3 循环链表

循环双向链表:与双向链表不同的是最后一个节点的next存储第一个节点的地址。第一个节点的pre存储最后一个节点地址。

 

 

循环单项链表也差不多。

二、代码简易实现

import java.util.*;


public class THS {
    public static void main(String[] args) {
        List<Integer> list = new List<>();
        list.linkLast(1);
        list.linkLast(2);
        list.linkLast(3);
        list.linkFirst(4);
        list.linkFirst(5);
        list.linkFirst(6);
        list.remove(5);
        list.printLink();
    }
}

//节点
class Node<E> {
    //存储当前节点的值
    E item;
    //存储下一个节点的地址
    Node<E> next;
    //存储上一个节点的地址
    Node<E> prev;

    public Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }

}

class List<E>{
    Node<E> first;
    Node<E> last;

    //头插节点
    void linkFirst(E e){
        Node<E> f = first;
        Node<E> temp = new Node<>(null,e,f);
        first = temp;
        if(f == null){
            last = temp;
        }else{
            f.prev = temp;
        }

    }
    //尾插节点
    void linkLast(E e){
        Node<E> l = last;
        Node<E> temp = new Node<>(l,e,null);
        last = temp;
        if (l == null){
            first = temp;
        }else{
            l.next = temp;
        }

    }
    boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unLink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unLink(x);
                    return true;
                }
            }
        }
        return false;
    }

    //移除节点
    void  unLink(Node<E> e){
        Node<E> preNode = e.prev;
        Node<E> nextNode = e.next;

        if (preNode == null){
            first = nextNode;
        }else {
            preNode.next = nextNode;
            e.prev = null;
        }
        if(nextNode == null){
            last = preNode;
        }else{
            nextNode.prev = preNode;
            e.next = null;
        }
        e.item = null;
    }

    void printLink(){
        if(first == null){
            System.out.println("空链表!!!");
        }else{
            Node<E> temp = first;
            while (temp!=null){
                System.out.println(temp.item);
                temp = temp.next;
            }
        }

    }

}














/**单例模式*/

//懒汉
class Singleton1{
    private static Singleton1 instance = null;
    private Singleton1(){}
    public static Singleton1 getInstance(){
        if (instance != null){
            instance = new Singleton1();
        }
        return instance;
    }
}
//饿汉
class Singleton2{
    private static final Singleton2 instance = new Singleton2();
    private Singleton2(){}
    public static Singleton2 getInstance(){
        return instance;
    }
}
//枚举
class Singleton3{
    private Singleton3(){}
    private enum Singleton{
        INSTANCE;
        private final Singleton3 instance;
        private Singleton(){
            instance = new Singleton3();
        }
        private Singleton3 getInstance(){
            return instance;
        }
    }
    public Singleton3 getInstance(){
        return Singleton.INSTANCE.getInstance();
    }
}
//双重校验锁
class Singleton4{
    private static volatile Singleton4 instance;
    private Singleton4(){}
    public static Singleton4 getInstance(){
        if(instance == null){
            synchronized (instance){
                if (instance == null){
                    instance = new Singleton4();
                }
            }
        }
        return instance;
    }
}

 

三、扩展

1、jdk1.8中LinkedList使用的是双向链表。

2、插入和删除的时间复杂度为o(1),查询为o(n)所以一般再插入删除多的情况下用链表。

posted @ 2022-10-11 11:22  大大怪下士  阅读(33)  评论(0编辑  收藏  举报