首页 > 其他分享 >【数据结构】单链表

【数据结构】单链表

时间:2024-08-06 09:55:44浏览次数:10  
标签:head 单链 cur next 链表 数据结构 linknode 节点

前言:小编这里将讨论无头单向非循环的单链表。

1.ArrayList的缺陷 

在上一期中,小编模拟了列表的相关操作实现,可以发现在增删的过程中非常麻烦,每次增加,或者删除数据的时候,都需要将操作下标的后面所有数据进行前移或者后移。

上期博客:http://t.csdnimg.cn/VI2yz

所以:

由于其底层是一段连续空间,当 ArrayList 任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后 搬移,时间复杂度为 O(n) ,效率比较低,因此 ArrayList 不适合做任意位置插入和删除比较多的场景 。因此: java集合中又引入了LinkedList ,即链表结构。

2链表的概念

链表是一种 物理存储结构上非连续 存储结构,数据元素的 逻辑顺序 是通过链表中的 引用链接 次序实现的。 分类: 单向或者双向

带头或者不带头 

循环或者非循环

  

当然小编这里将讨论单向非循环; 

 3.链表的实现

3.1.初始化链表

 static class linknode{
        public int val;
        public linknode next;
        public linknode(int val){
            this.val=val;
        }
    }
    public linknode head;

首先定义一个类代表链表,在类中定义一个静态内部类,代表一个节点,节点内有值域,以及一个指针域。并在在构造函数中声明数值,方便在函数实例化时进行赋值操作,最后初始话一个头节点

3.2.链表赋值

 public void createList(){
        linknode node1=new linknode(12);
        linknode node2=new linknode(12);
        linknode node3=new linknode(14);
        linknode node4=new linknode(15);
        linknode node5=new linknode(16);
        linknode node6=new linknode(17);
        node1.next=node2;
        node2.next=node3;
        node3.next=node4;
        node4.next=node5;
        node5.next=node6;

        this.head=node1;
    }

实例化多个节点,并通过指针域进行相邻节点相连,但是小编不建议这么编写。

3.3.链表的头插法

 public void addFirst(int data){
        linknode node=new linknode(data);
        node.next=head;
        this.head=node;
    }

 图解:

所以 节点的next就为头结点,然后将头结点给node.

3.4.链表的尾插法

public void addLast(int data){
        linknode cur=head;
        linknode node=new linknode(data);
        while (cur.next!=null){
            cur=cur.next;
        }
        cur.next=node;
    }

与头插法相似,实例化节点,通过遍历链表,将cur节点next到链表末尾,最后通过cur节点指针域指向实例化的节点,实现尾插法。

3.5.在任意位置实现插入

public void addIndex(int index,int data){
        linknode cur=head;
        linknode node=new linknode(data);
        if (index==0){
            addFirst(data);
            return;
        }
        if (index==size()){
            addLast(data);
            return;
        }
        for (int i = 0; i <index-1; i++) {
            cur=cur.next;
        }
        node.next=cur.next;
        cur.next=node;
    }

判断插入位置是哪里,如果为0,即为头插法,如果为链表末尾,就是尾插法。

最后找到插入位置的前一个节点,通过改变指针域的指向地址,实现插入。

3.6.值是否存在链表中

 public boolean contains(int key){
        linknode cur=head;
        while (cur.next!=null){
            if (cur.val==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }

通过遍历每个节点,然后通过比较每个节点的数值域,如果存在则返回true,反之遍历完后,不存在则返回false。

3.7.删除第一次遇到的数值

 public void remove(int key){
        linknode cur=head;
        if (head.val==key){
            head=head.next;
            return;
        }
        while (cur.next!=null){
            if(cur.next.val==key){
                cur.next=cur.next.next;
                return;
            }
            cur=cur.next;
        }
    }

首先判断头结点的数值域是否等于key,等于就将头结点等于下一个节点。

反之遍历链表,如果存在该数值,就应该在数值的前一个节点进行操作,实现要删除节点的跳过操作。

3.8.实现所有key数值的删除

 public void removeAllKey(int key){
        linknode cur=head;
        linknode prve=head;
        while (cur!=null){
            if (cur.val==key){
                prve.next=cur.next;
                cur=cur.next;
            }else {
                prve=cur;
                cur=cur.next;
            }
        }
        if(head.val==key){
            head=head.next;
        }
    }

图解

首先我们定义两个节点 等于头结点,其中cur每次循环都要指向下一个节点,且如果不存在key时,prve倒要保持在cur节点的前一个,如果发现了key,则通过prve进行跳过,若存在重复,则,再次通过cur进行判断,在次通过prve进行跳过实现链接。

最后由于,头结点没有判断,就要进行头结点的判断。

3.9.实现链表的长度以及打印

public int size(){
        int size=1;
        linknode cur=head;
        while (cur.next!=null){
            cur=cur.next;
            size++;
        }
        return size;
    }
    public void clear() {
        this.head=null;
    }
    public void display() {
        linknode cur=head;
        while (cur!=null){
            System.out.print(cur.val+" ");
            cur=cur.next;
        }
    }

通过遍历链表,在节点不为空的情况下,每次循环长度加一,并且进行每个节点数值域的打印。

4.结束语

小编下一期将进行单向链表的相关题目讲解,想了解的uu关注一下吧。

限于小编能力有限,可能存在一些错误,希望各位uu提出宝贵意见,望指正。

制作不易,麻烦给小编一个赞吧。

标签:head,单链,cur,next,链表,数据结构,linknode,节点
From: https://blog.csdn.net/GGBond778/article/details/140938230

相关文章

  • 手撕数据结构之二叉树
     1.树树的基本概念与结构树是⼀种⾮线性的数据结构,它是由n(n>=0)个有限结点组成⼀个具有层次关系的集合。把它叫做树是因为它看起来像⼀棵倒挂的树,也就是说它是根朝上,⽽叶朝下的。•有⼀个特殊的结点,称为根结点,根结点没有前驱结点。•除根结点外,其余结点被分成M(M>0)......
  • 数据结构 顺序表 -- C语言实现
    顺序表概念顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。顺序表一般可以分为:静态顺序表:使用定长数组存储元素。动态顺序表:使用动态开辟的数组存储。代码实现动态顺序表静态顺序表只适用于确定......
  • 【Java数据结构】---初始数据结构
    乐观学习,乐观生活,才能不断前进啊!!!我的主页:optimistic_chen我的专栏:c语言,Java欢迎大家访问~创作不易,大佬们点赞鼓励下吧~前言从今天开始我们就要学习Java的数据据结构部分,根据前面Java语法的基础上,更加深入的了解算法的基本知识。文章目录前言什么是数据结......
  • 数据结构 顺序与链式二叉树的原理与实现(万字)
    目录一、树概念及结构树的概念树的相关概念树的表示二、二叉树概念及结构概念特殊的二叉树二叉树的性质二叉树的存储结构三、二叉树的顺序结构及实现二叉树的顺序结构堆的概念及结构堆的实现堆向下调整算法堆的创建建堆时间复杂度堆的插入堆的删除堆的代码实现Heap.hHeap.c堆的应......
  • 【数据结构】一文总结算法的时间复杂度与空间复杂度
    目录一.算法的复杂度二.时间复杂度1.概念2.大O的渐进表示法3.实践练习3.1练习13.2 练习23.3 练习33.4练习43.5练习5三.空间复杂度 1.概念2.实践练习2.1练习12.2练习22.3练习32.4练习4四.编程题练习 1. 消失的数字2.轮转数组 一.......
  • 【数据结构】Map和Set
    目录1.前言2.搜索树2.1概念2.2操作-查找2.3操作-插入2.4操作-删除2.5性能分析3.搜索3.1概念及场景3.2模型3.3Map的使用3.3.1关于Map的说明3.3.2关于Map.Entry的说明,>3.3.3Map的常用方法说明3.3.4TreeMap的使用3.4Set的使用3.4.1Set的说明3.4.2Set的常......
  • 《数据结构习题解析与实验指导_李冬梅,张琪编著》总结出的大纲
        下面大纲为《数据结构习题解析与实验指导_李冬梅,张琪编著》总结出的大纲,可装13学习下:          ......
  • 数据结构-2.单向链表的实现
    节点结构体设计structLinkNode{ //数据域 void*data; //指针域 structLinkNode*next;};data:一个void*类型的指针,指向节点存储的数据。使用void*是为了链表能够存储不同类型的数据。next:一个指向下一个LinkNode结构体的指针,形成链表的链接。链表结构体设......
  • 数据结构内核链表的代码
    说明内核链表的诞生原因呢,就是为了把数据域和指针域分开来就形成了下面这样的链表structlist{structlist*prev;//存放前缀节点的指针structlist*next;//存放后缀节点的指针};那有的读者会疑问,那数据放哪里?//节点结构体structnode{//以整型数......
  • (链表基础)PTA习题11-8 单链表结点删除
    题目要求:本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中所有存储了某给定值的结点删除。链表结点定义如下:structListNode{intdata;ListNode*next;};函数接口定义:structListNode*readlist();structListNode*deletem(structListNode*L,......