Java数据结构-------单链表(图解增删改查详细实现,附反转链表实现)(下)

简介: Java数据结构-------单链表(图解增删改查详细实现,附反转链表实现)(下)

4.向指定位置i处插入元素t


//向指定位置i处添加元素
    public void insert(int i,T t){
        //找到i位置前一个结点
       Node pre=head;
       for(int j=0;j<=i-1;i++){
           pre=pre.next;
       }
       //找到i位置的结点
        Node curr =pre.next;
       //创建新节点,并且新结点需要指向原来i位置的结点
        Node newNode=new Node(t,curr);
        //原来i位置的前一个节点指向新结点即可
        pre.next=newNode;
        N++;
    }

解析:在指定位置插入元素,类似我们上面在结尾添加元素,但插入时我们不仅要让i位置前一个结点next新节点,还要让新结点的next指向i位置后一个结点。我们先通过遍历找到i位置的前一个结点并记录为pre,此时我们pre.next就是我们i位置处的结点,我们保存为curr。这时我们创建新节点newNode,它的数据域为t,指针域为我们的curr,也就是原来i位置上的结点,这时我们再让pre指向newNode就完成了我们的插入操作。可以看看下面的图解步骤


image.png


对于指定位置的插入操作,顺序表需要对大量的元素进行移动,效率很低,如果你想在下标为0处插入,甚至需要整个数组进行后移。而链表相对于顺序表最显著的优点就在这,它在插入时完全不需要考虑移动元素,因为它的地址是不连续的,它可以在任意地方开辟空间生成结点。


5.删除指定位置i处的元素,并返回该元素


//删除指定位置处i处的元素,并返回被删除的元素
    public T remove(int i){
        Node pre=head;
          //先找到i处前一个结点
        for (int j = 0; j <= i - 1; j++) {
            pre=pre.next;
        }
           //记录i处的结点
        Node n=pre.next;
            //让i处前一个结点指向i处后一个结点
        pre.next=n.next;
        N--;
        return n.item;
    }

解析:删除的操作很简单,我们同样通过遍历得到i处的前一个元素并记录为pre,再将pre.next也就是i处的结点记录为n。然后我们让n.next赋值给pre.next,也就是让i处前一个结点(pre)指向i处后一个结点


下面为简易图解


image.png


6.查找元素第一次出现的位置


//查找元素第一次出现的位置
    public int indexOf(T t){
        Node pre=head;
        for (int i = 0;pre.next!=null; i++) {
            pre=pre.next;
            if(pre.item==t) return i;
        }
        return -1;
    }

解析:从头开始遍历,每次判断是否是我们需要查找的结点,如果是直接返回,如果遍历完仍未找到,则返回-1,表示链表中没有需要查找的元素。


7.反转链表


该内容为补充内容,反转链表不属于链表的功能,但我们也需要了解,技多不压身。


//用来反转整个链表
    public void reverse(){
        //判断当前链表是否为空,如果为空则结束运行
        if(isEmpty())   return;
        reverse(head.next);
    }
    //反转指定的某个结点
    public Node reverse(Node curr){
        if(curr.next==null){
            head.next=curr;
            return curr;
        }
        //递归的反转当前结点curr的下一个结点,返回值就是链表反转后,当前结点的上一个结点
        Node pre=reverse(curr.next);
        //让返回的结点的下一个结点变为当前结点curr
        pre.next=curr;
        //把当前的下一个结点变为null
        curr.next=null;
        return curr;
    }

解析:这个代码最好通过debug一步步去理解它,它会在Node pre=reverse(curr.next)这个地方一直进入循环,因为要满足if循环中的某个结点curr.next为null,那么只有链表中的最后一个结点,此时让头结点指向它,也就是下图中的第一次递归完的情况。但我们要清楚在我们将最后一个结点传入这个方法时,此时是在倒数第二个结点为curr的情况下,因为此时curr这个结点在这个方法体中,在if判断中它不成立,因为它后面还有链表最后一个结点,前面的结点也是如此,所以if判断条件都不通过,但此时curr传入它的next进入循环后,我们姑且称之为尾结点,尾结点在if判断中是成立的,它在完成反转后,也就是让头结点指向它后,将自己返回。这时尾结点被一个pre接收,然后pre.next=curr,也就是让最后一个结点指向倒数第二个结点,接着将倒数第二个结点返回,然后继续递归,如图:


image.png


总结:单链表和顺序表一样属于基础数据结构,需要我们掌握并熟悉它的功能,反转链表部分我的表达可能不是很清楚,不明白的同学可以自己画图一步步debug,毕竟数据结构很抽象,需要我们画图才更易理解

相关文章
|
4月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
198 3
|
6月前
|
前端开发 Java
java实现队列数据结构代码详解
本文详细解析了Java中队列数据结构的实现,包括队列的基本概念、应用场景及代码实现。队列是一种遵循“先进先出”原则的线性结构,支持在队尾插入和队头删除操作。文章介绍了顺序队列与链式队列,并重点分析了循环队列的实现方式以解决溢出问题。通过具体代码示例(如`enqueue`入队和`dequeue`出队),展示了队列的操作逻辑,帮助读者深入理解其工作机制。
167 1
|
6月前
|
存储 Java 编译器
Java 中 .length 的使用方法:深入理解 Java 数据结构中的长度获取机制
本文深入解析了 Java 中 `.length` 的使用方法及其在不同数据结构中的应用。对于数组,通过 `.length` 属性获取元素数量;字符串则使用 `.length()` 方法计算字符数;集合类如 `ArrayList` 采用 `.size()` 方法统计元素个数。此外,基本数据类型和包装类不支持长度属性。掌握这些区别,有助于开发者避免常见错误,提升代码质量。
478 1
|
8月前
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
203 30
|
8月前
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
318 25
|
9月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
346 5
|
10月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
10月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
146 5
|
11月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
288 5
|
11月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
173 4