当前位置: 首页 > article >正文

无头双向链表模拟实现

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

实现代码:

创建3个类

public class MyLinkedList {
    //通过内部类来实现
    static class ListNode {
        private int val;
        private ListNode prev;
        private ListNode next;

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

        public int getVal() {
            return val;
        }

        public void setVal(int val) {
            this.val = val;
        }
    }
    public ListNode head;//双链表的头结点
    public ListNode last;//双链表的尾巴
    //头插法
    public void addFirst(int data){
        ListNode node=new ListNode(data);
        if(head==null){
            head=node;
            last=node;
        }else {
            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;
        }else {
           last.next=node;
           node.prev=last;
           last=node;
        }
    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
        checkIndex(index);
        if(index==0){
            addFirst(data);
        }
        if (index==size()){
            addLast(data);
        }
        ListNode node=new ListNode(data);
        ListNode cur=searchIndex(index);
        node.next=cur;
        cur.prev.next=node;
        node.prev=cur.prev;
        cur.prev=node;


    }
    //检查数据的合法性
    public boolean checkIndex(int index){
        if(index<0||index>size()){
            throw new IndexOutOFException("index位置不合法!"+index);
        }
        return true;
    }
    //寻找index的位置
    private ListNode searchIndex(int index){
        ListNode cur=head;
        while (index!=0){
            cur=cur.next;
            index--;
        }
        return cur;
    }
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur=head;
        while (cur!=null){
            if(cur.val==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }
    //删除第一次出现关键字为key的节点
    public void remove(int key){
        ListNode cur=head;
        while (cur!=null){
            if (cur.val==key){
                //删除头结点
                if (cur==head){
                    head=head.next;
                    if(head!=null){
                        //考虑只有一个节点的情况下
                        head.prev=null;
                    }else {
                        last=null;
                    }
                }else {
                    //删除中间节点和尾巴节点
                    if(cur.next!=null){
                        //删除中间节点
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                    }else {
                        //删除尾巴节点
                        cur.prev.next=cur.next;
                        last=last.prev;
                    }
                }
                return;
            }else {
                cur=cur.next;
            }
        }
    }
    //删除所有值为key的节点
    public void removeAllKey(int key){
        ListNode cur=head;
        while (cur!=null){
            if (cur.val==key){
                //删除头结点
                if (cur==head){
                    head=head.next;
                    if(head!=null){
                        //考虑只有一个节点的情况下
                        head.prev=null;
                    }else {
                        last=null;
                    }
                }else {
                    //删除中间节点和尾巴节点
                    if(cur.next!=null){
                        //删除中间节点
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                    }else {
                        //删除尾巴节点
                        cur.prev.next=cur.next;
                        last=last.prev;
                    }
                }
                cur=cur.next;
            }else {
                cur=cur.next;
            }
        }
    }
    //得到单链表的长度
    public int size(){
        ListNode cur=head;
        int len=0;
        while (cur!=null){
            len++;
            cur=cur.next;
        }
        return len;
    }
    public void display(){
        ListNode cur=head;

        while (cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
    }
    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;
    }
}

2.异常类

public class IndexOutOFException extends RuntimeException{
    public IndexOutOFException() {
    }

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

3.测试类

public class Test {
    public static void main(String[] args) {
        MyLinkedList myLinkedList=new MyLinkedList();
        myLinkedList.addLast(1);
        myLinkedList.addLast(2);
        myLinkedList.addLast(3);
        myLinkedList.addLast(4);
        //System.out.println(myLinkedList.contains(2));
        //System.out.println(myLinkedList.size());
        //myLinkedList.addIndex(2,99);
        //myLinkedList.remove(2);
        //myLinkedList.removeAllKey(1);
        myLinkedList.clear();
        myLinkedList.display();
    }
}

使用:

. LinkedList 的其他常用方法介绍
方法
解释
boolean add (E e)
尾插 e
void add (int index, E element)
e 插入到 index 位置
boolean addAll (Collection<? extends E> c)
尾插 c 中的元素
E remove (int index)
删除 index 位置元素
boolean remove (Object o)
删除遇到的第一个 o
E get (int index)
获取下标 index 位置元素
E set (int index, E element)
将下标 index 位置元素设置为 element
void clear ()
清空
boolean contains int 
判断o是否在线性表中
indexOf(Object o)(Object o)返回第一个 o 所在下标
int lastIndexOf(Object o)返回最后一个 o 的下标
List<E> subList(int fromIndex, int toIndex)截取部分 list

ArrayListLinkedList的区别


http://www.kler.cn/a/375301.html

相关文章:

  • 【AI日记】24.11.01 LangChain、openai api和github copilot
  • Qt指定程序编译生成文件的位置
  • Java Executor ScheduledExecutorService 源码
  • Oasis 500M:开源的实时生成交互式视频内容的 AI 模型
  • 龙迅#LT8668EX显示器图像处理芯片 适用于HDMI1.4+VGA转4PORT LVDS,支持4K30HZ分辨率,可做OSD菜单亮度调节!
  • 硅谷(12)菜单管理
  • 数据库->数据库约束
  • nacos快速启动
  • markdown/Latex分子,分母,除号,怎么编辑
  • NET Core的AOP实施方法1 DispatchProxy
  • SAP(PP生产制造)拆解工单业务处理
  • YOLO11改进 | 卷积模块 | 提高网络的灵活性和表征能力的动态卷积【附代码+小白可上手】
  • 基于NVIDIA NIM平台实现盲人过马路的demo(一)
  • LeetCode516:最长回文子序列
  • 从0到1,用Rust轻松制作电子书
  • OpenWrt下安装Mosquitto
  • 在Java中 try catch 会影响性能吗?
  • 轻松部署自己的AI聊天助手LocalGPT并实现无公网IP远程交互
  • 包子凑数(完全背包)
  • 详解进制转换
  • windows@命令行中获取环境变量取值不展开取值(原值)
  • 大数据新视界 -- 大数据大厂都在用的数据目录管理秘籍大揭秘,附海量代码和案例
  • 青少年编程与数学 02-003 Go语言网络编程 03课题、网络编程协议
  • 代码随想录训练营Day09 | 150. 逆波兰表达式求值 - 239. 滑动窗口最大值 - 347.前 K 个高频元素
  • 从服务运营的阶段,进入到了精细化管理和智慧化运营的阶段的明厨亮早年开源了
  • ubuntu知识点滴积累