数据结构之单链表

请添加图片描述

一、前言

在上篇文章中,我们详细的讲解了顺序表,这里链接给大家放在下面。没看过的同学可以看一看,因为单链表就是在顺序表之上,做出优化的线性表。

新学期预习吗?保姆级讲解数据结构之顺序表的9个方法+手撕代码

大家还记得顺序表中的add方法吗?那写起来简直是一个麻烦,又要考虑pos下标是否合法,还得一个一个的把后面的元素移到前面,这样一来,不仅代码写起来麻烦,代码执行的时间复杂度也高。但也不是没有优点。


顺序表:由数组构成,那么它也就包含了数组的特性。

优点:
1、查询元素时非常方便快捷,可以通过一个下标,能够快速的找到当前的数据。O(1).

缺点:
1、每次都会浪费大小不等的内存,假设当前数组大小为20;如果你要放第21个元素的时候,就需要扩容,假设扩容2倍后,大小是40,只放一个元素,那么剩下19个就浪费掉了。
2、每次扩容的时候,都需要拷贝数组的内容,拷贝的过程中也是需要时间的,造成一定程度资源的浪费。
3、删除和插入数据的时候,都需要移动数据。

那么问题来了,有没有一种表,又不浪费内存,删除、插入数据的时候还方便快捷呢?
请添加图片描述


这时候能够解决上面三个问题的链表来了!

二、什么是链表?

2.1、链表的概念:

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

在这里插入图片描述
2.2、链表的分类:链表的结构非常多样化,根据带头和不带头,双向和单向,循环和不循环可以组成很多种链表。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

随便链表的种类有很多,但是只需要重点掌握两种即可。


2.2、两种重要的单链表

1、无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。

在这里插入图片描述
1、无头双向循环链表:在Java集合框架当中,LinkedList的底层就是由这种链表实现的。

在这里插入图片描述
注意:每个链表的400、200、300均为节点的引用地址,实际上是以16进制的方式存储的,这里我为了画图方便,进行了简写。


2.3、关于单链表的一些基础知识

1、链表在逻辑上是连续的,但是物理上不一定是连续的。这里的物理上,指的是内存地址上。

2、单链表的值域:
对于单链表来说,每一个节点都3个属性,在下图中最上面的123,指的是当前节点的地址(本来应该是16进制,这里为了方便说明用10进制)。val域:val是value的缩写,就是值的意思,这里存放的是当前节点需要存储的信息。
next域:它的类型是一个节点类型。由于单链表在逻辑上是连续的,故对于一个节点来说,它不仅需要存放自己的val值,它还需要存放自己的下一个节点的地址->next,以此来实现逻辑上的连续。

在这里插入图片描述
3、单链表的结构

头节点+数据节点

在这里插入图片描述


三、单链表的实现

光说不练假把式,我们了解了链表的结构、用处。现在我们来亲手实现一个自己的单链表。

3.1、穷举法创建一个简单的链表

这里我先用穷举的方式一一创建节点,这样方便理解,下文再讲述用其他方法创建链表

public class MylinkedList {
   
    public  ListNode head;//标识这个链表的头
    /**
     * 穷举法,最简单的方式把链表一个一个列举出来。
      */
    public  void createList(){
   
        ListNode listNode1=new ListNode(12);
        ListNode listNode2=new ListNode(13);
        ListNode listNode3=new ListNode(23);
        ListNode listNode4=new ListNode(33);
        ListNode listNode5=new ListNode(44);
        listNode1.next=listNode2;
        listNode2.next=listNode3;
        listNode3.next=listNode4;
        listNode4.next=listNode5;
        //head引用 引用的是listNode1引用 引用的对象
        this.head=listNode1;

    }
}
class ListNode{
   
   public  int val;//值
   public ListNode next;//储存下一个节点的地址,它是一个引用

    /**
     * 不带参数的构造方法
     */
    public  ListNode(){
   

    }
    /**
     * 带一个参数的构造方法
     */
    public  ListNode(int val){
   
       this.val=val;
   }
}

现在链表有了,那么问题来了,数组可以通过for循环的方式遍历链表,或者直接通过数组下标找到某个节点,那如何遍历链表当中的每个元素呢?

在这里插入图片描述

先看这样一行代码:

head=head.next<
  • 244
    点赞
  • 849
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 47
    评论
评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

见闻色霸气~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值