数据结构(Java实现)LinkedList与链表(下)


**

**












结论

让一个指针从链表起始位置开始遍历链表,同时让一个指针从判环时相遇点的位置开始绕环运行,两个指针都是每次均走一步,最终肯定会在入口点的位置相遇。


LinkedList的模拟实现

单个节点的实现



尾插


运行结果如下:




也可以暴力使用


全部代码

MyLinkedList

java 复制代码
public class MyLinkedList {
    static class ListNode{
        public  int val;
        public ListNode prev;
        public ListNode next;

        public ListNode(int val) {
            this.val = val;
        }
    }
    public  ListNode head;
    public  ListNode last;

    //链表的长度
    public int size(){
        int len=0;
        ListNode cur=head;
        while(cur!=null){
            cur=cur.next;
            len++;
        }
        return len;
    }

    //打印链表
    public  void dispaly(){
        ListNode cur=head;
        while(cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
        System.out.println();
    }

    //查找关键字key是否在链表中
    public boolean contains(int key){
        ListNode cur=head;
        while(cur!=null){
            if(cur.val==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }

    //头插
public void addFirst(int data){
    ListNode node=new ListNode(data);
    //空链表
    if(head==null){
        head=node;
        last=node;
        return;
    }
    //一般情况
    node.next=head;
    head.prev=node;
    head=node;
    }

    //尾插
    public void addLast(int data){
        ListNode node=new ListNode(data);
        //空链表
        if(head==null){
            head=node;
            last=node;
            return;
        }
        //一般情况
        last.next=node;
        node.prev=last;
        last=node;
    }
//无论是头插还是尾插,只要是空链表,那么新增节点的next和prev都引用自身

    //任意位置的插入,在位置后面插入
    public void AddIndex(int index,int data){
        ListNode node=new ListNode(data);

        if(index<0||index>size()){
            throw new IndexOutOfBounds("任意位置插入,坐标非法,非法值为"+index);
        }
        if(index==0){
            addFirst(data);
            return;
        }
        if(index==size()){
            addLast(data);
            return;
        }

        //一般情况
        ListNode cur=head;
        while(index!=0){
            cur=cur.next;
            index--;
        }
        node.next=cur;
        cur.prev.next=node;
        node.prev=cur.prev;
        cur.prev=node;

    }

//删除第一次出现关键字为key的节点
    public void remove(int key){

        //链表为空
        if(head==null){
            return;
        }
        //只有一个节点并且该节点值为key
        if(head.next==null&&head.val==key){
            head.prev=null;
            head.next=null;
            return;
        }
        //头节点
        if(head.val==key)
        {
            head.next.prev=null;
            head=head.next;
            return;
        }
        //尾节点
        if(last.val==key){
            last.prev.next=null;
            last=last.prev;
            return;
        }
        //一般情况
        ListNode cur=head;
        while(cur!=null){
            if(cur.val==key){
                cur.prev.next=cur.next;
                cur.next.prev=cur.prev;
                return;
            }
            cur=cur.next;
        }
    }

    //删除所有出现关键字为key的节点
    public void removeAll(int key){

        //链表为空
        if(head==null){
            return;
        }
        //只有一个节点并且该节点值为key
        if(head.next==null&&head.val==key){
            head.prev=null;
            head.next=null;
            return;
        }
        //头节点
        if(head.val==key)
        {
            head.next.prev=null;
            head=head.next;

        }
        //尾节点
        if(last.val==key){
            last.prev.next=null;
            last=last.prev;

        }
        //一般情况
        ListNode cur=head;
        while(cur!=null){
            if(cur.val==key){
                cur.prev.next=cur.next;
                cur.next.prev=cur.prev;
            }
            cur=cur.next;
        }
    }


    //clear
    public  void clear(){
/*        ListNode cur=head;
        while(cur!=null){
            ListNode curNext=cur.next;//存储下一个节点,方便下次循环使用
            cur.prev=null;
            cur.next=null;
            cur=curNext;//更新当前节点
        }*/
        head=null;
        last=null;//使头节点和尾节点的地址置空
    }

}

IndexOutOfBounds

java 复制代码
public class IndexOutOfBounds extends  RuntimeException{
    public IndexOutOfBounds() {
    }

    public IndexOutOfBounds(String message) {
        super(message);
    }
}

Test1

java 复制代码
public class Test1 {
    public static void main(String[] args) {
        MyLinkedList myLinkedList=new MyLinkedList();
        myLinkedList.addFirst(34);
        myLinkedList.addFirst(3);
        myLinkedList.addFirst(4);
        myLinkedList.addFirst(340);
        myLinkedList.addFirst(344);
        myLinkedList.dispaly();
        System.out.println(myLinkedList.size());
        System.out.println(myLinkedList.contains(4));
        System.out.println("我是分割线");
        myLinkedList.addLast(-12);
        myLinkedList.addLast(-121);
        myLinkedList.addLast(-1222);
        myLinkedList.dispaly();
        myLinkedList.AddIndex(3,999);
        myLinkedList.dispaly();
       // myLinkedList.AddIndex(55,999);
        System.out.println("我是分割线");
        myLinkedList.remove(999);
        myLinkedList.dispaly();
        myLinkedList.remove(344);
        myLinkedList.dispaly();
        myLinkedList.addFirst(-12);
        myLinkedList.addLast(-12);
        myLinkedList.dispaly();
        myLinkedList.removeAll(-12);
        myLinkedList.dispaly();
        System.out.println("我是分割线");
        myLinkedList.clear();
        myLinkedList.dispaly();
        System.out.println("证明有空行");


    }
}

什么是LinkedList

LinkedList的底层是双向链表结构(链表后面介绍),由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此在在任意位置插入或者删除元素时,不需要搬移元素,效率比较高。


LinkedList的使用


LinkedList的其他常用方法



LinkedList的遍历


ArrayList和LinkedList的区别


相关推荐
csgo打的菜又爱玩8 小时前
数仓整体架构和建模架构
java·大数据·开发语言·架构
翱翔的苍鹰8 小时前
多Agent智能体系统设计思路
java·python·深度学习·神经网络·机器学习·tensorflow
小花8 小时前
java后端框架之spring
java·开发语言·spring
一条大祥脚8 小时前
势能分析与势能线段树
开发语言·javascript·数据结构·算法
小王不爱笑1328 小时前
Spring Boot 配置文件核心用法与加载优先级
java·spring boot·后端
一起养小猫8 小时前
Flutter实战:从零实现俄罗斯方块(一)数据结构与核心算法
数据结构·算法·flutter
小北方城市网8 小时前
Spring Cloud Gateway 动态路由进阶:基于 Nacos 配置中心的热更新与版本管理
java·前端·javascript·网络·spring boot·后端·spring
橙露8 小时前
Docker 容器化运维:镜像优化、容器编排与持久化存储方案
java·运维·docker
码农阿豪8 小时前
SpringAI 实战:构建智能问答系统全流程解析
java·人工智能
亿秒签到8 小时前
第六届传智杯程序设计国赛B组T4·小苯的字符串染色
数据结构·算法·传智杯