Java 精炼解读数据结构的链表的概念与实现

目录
  • 前言:
  • 一、什么是链表
    • 链表的概念
    • 链表的结构
    • 链表如何存储数据
    • 链表的实现  
    • 穷举法创建链表
    • 打印链表
    • 查找是否包含关键字key是否在单链表当中 
    • 得到单链表的长度:
    • 头插法
    • 尾插法
    • 任意位置插入,第一个数据节点为0号下标
    • 删除第一次出现关键字为key的节点
    • 删除所有值为key的节点
  • 总结:

前言:

顺序表的问题及思考

1. 顺序表中间/头部的插入删除,时间复杂度为O(N)

2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。

3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续 插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

思考: 如何解决以上问题呢?下面给出了链表的结构来看看。

一、什么是链表

链表的概念

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

链表的结构

链表结构分为8种:

这里我们只讲最下面两种,因为在工作中、业务里、考试题、刷到的链表题、面试题里面都是用到这两种链表。 

链表如何存储数据

链表是由一个一个节点组成的。(这里我们以单链表为例)

什么叫做节点?

节点分为两个域 ,假设一个叫做val域,一个叫做next域。

val:数据域

next:下一个节点的地址

链表的实现  

//ListNode代表一个节点

class ListNode{
    public int val;
    public ListNode next;

    //构造方法
    public ListNode(int val){
        this.val = val;
    }
}
//MyLinkedList 代表这是一个链表

public class MyLinkedList {
    public ListNode head;//链表的头引用,所以定义在链表里,head是链表的头,不是节点的头,节点只有两个属性,一个属性是val值,一个属性是next值,所以不能定义在ListNode类里面
    ListNode listNode = new ListNode(2);//节点实例化,val域赋值为2
}

穷举法创建链表

/MyLinkedList 代表这是一个链表
public class MyLinkedList {
    public ListNode head;//链表的头引用,所以定义在链表里
    public  void createList(){
        ListNode listNode0 = new ListNode(11);
        ListNode listNode1 = new ListNode(26);
        ListNode listNode2 = new ListNode(23);
        ListNode listNode3 = new ListNode(45);
        ListNode listNode4 = new ListNode(56);
        listNode0.next = listNode1;
        listNode1.next = listNode2;
        listNode2.next = listNode3;
        listNode3.next = listNode4;
        this.head = listNode0;
    }

打印链表

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

打印结果:

查找是否包含关键字key是否在单链表当中 

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

打印结果:

得到单链表的长度:

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

 打印结果:

头插法

 //头插法

    public void addFirst(int data) {
        ListNode node = new ListNode(data);
        if (this.head == null) {
            this.head = node;
        } else {
            node.next = this.head;
            head = node;
        }
    }

打印结果:

尾插法

//尾插法

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

        }
    }

打印结果:

任意位置插入,第一个数据节点为0号下标

public ListNode findIndex(int index){
        ListNode cur = this.head;
        while(index -1 != 0){
            cur = cur.next;
            index--;
        }
        return cur;

    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
        if(index < 0 || index > size()){
            System.out.println("位置不合法");
            return;
        }
            if(index == 0){
                addFirst(data);
                return;
            }
            if(index == size()){
                addLast(data);
                return;
            }

            ListNode cur = findIndex(index);
            ListNode node = new ListNode(data);
            node.next = cur.next;
            cur.next = node;

    }

打印结果:

删除第一次出现关键字为key的节点

//删除第一次出现关键字为key的节点
    public void remove(int key){
        if(this.head == null){
            System.out.println("没有你要删除的节");
            return;
        }
       if (this.head.val == key){
           this.head = this.head.next;
           return;
        }
       ListNode cur = this.head;
       while (cur.next != null){
           if(cur.next.val == key){
               cur.next = cur.next.next;
               return;
           }
           cur = cur.next;
       }
       if(cur.next == null){
           System.out.println("没有该节点");
           return;
       }

    }

打印结果:

删除所有值为key的节点

    //删除所有值为key的节点
    public ListNode removeAllKey(int key){
        if(this.head == null) return null;
        ListNode prev = this.head;
        ListNode cur = this.head;
        while (cur != null){
            if(cur.val == key){
                prev.next = cur.next;
                cur = cur.next;
            }else{
                    prev = cur;
                    cur = cur.next;
            }
        }
        if(this.head.val == key){
            this.head = this.head.next;
        }
        return this.head;

    }

打印结果:

总结:

本文简单介绍了数据结构的链表,如何创建链表,链表上如何操作数据。通过简单例题的方式加深对顺序表的理解。上述就是今天的内容,有任何疑问的话可以随时私信我,文章哪里出现了问题我都会积极改正,也希望大家能更快的掌握自己想要的知识,让我们一起加油!!!!!

到此这篇关于Java 精炼解读数据结构的链表的概念与实现的文章就介绍到这了,更多相关Java 数据结构的链表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java实现链表数据结构的方法

    什么是链表? 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的.每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址). 链表的理解示意图: 链表的特点是什么? 获取数据麻烦,需要遍历查找,比数组慢方便插入.删除 简单的链表的实现原理 创建一个节点类,其中节点类包含两个部分,第一个是数据域(你到时候要往节点里面储存的信息),第二个是引用域(相当于指针,单向链表有一个指

  • Java 数据结构与算法系列精讲之单向链表

    目录 概述 链表 单向链表 单向链表实现 Node类 add方法 remove方法 get方法 set方法 contain方法 main 完整代码 概述 从今天开始, 小白我将带大家开启 Jave 数据结构 & 算法的新篇章. 链表 链表 (Linked List) 是一种递归的动态数据结构. 链表以线性表的形式, 在每一个节点存放下一个节点的指针. 链表解决了数组需要先知道数据大小的缺点, 增加了节点的指针域, 空间开销较大. 链表包括三类: 单向链表 双向链表 循环链表 单向链表 单向链表

  • Java 数据结构与算法系列精讲之环形链表

    目录 概述 链表 环形链表 环形链表实现 Node类 insert方法 remove方法 main 完整代码 概述 从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章. 链表 链表 (Linked List) 是一种递归的动态数据结构. 链表以线性表的形式, 在每一个节点存放下一个节点的指针. 链表解决了数组需要先知道数据大小的缺点, 增加了节点的指针域, 空间开销较大. 链表包括三类: 单向链表 双向链表 循环链表 环形链表 环形链表 (Circular Linked Li

  • java数据结构实现双向链表功能

    双向链表实现 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点. 注意:在操作双向链表时,不要去移动指向前驱节点和后继节点的指针,而是重新定义指向头尾的指针进行移动.* 环境 IDEA 自定义操作接口 双向链表. public interface MyList<E> { void add(E node); E get(int index); E remove(int in

  • Java数据结构与算法学习之循环链表

    目录 存储结构示意图 初始化循环链表  循环链表的插入 首位置 代码实现 其他位置 代码实现(总) 循环链表的删除 1.操作的为第一个元素 2.操作元素不为第一个元素 代码实现(总) 循环链表的常见操作  存储结构示意图 优点 : 能够通过任意结点遍历整个链表结构 初始化循环链表  1.循环链表的结点 typedef struct CircularNode { ElementType date; //数据域 struct CircularNode* next; //指向下一个结点的指针域 }Ci

  • 带你了解Java数据结构和算法之链表

    目录 1.链表(Linked List) 2.单向链表(Single-Linked List) ①.单向链表的具体实现 ②.用单向链表实现栈 4.双端链表 ①.双端链表的具体实现 ②.用双端链表实现队列 5.抽象数据类型(ADT) 6.有序链表 7.有序链表和无序数组组合排序 8.双向链表 9.总结 前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会

  • Java数据结构之顺序表和链表精解

    目录 前言 1. 顺序表 代码实现 2. 链表 链表图解 代码实现 前言 两个数据结构:顺序表和链表 数据结构是一门学科,和语言无关. 数据 + 结构:一种描述和组织数据的方式. 1. 顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储.在数组上完成数据的增删查改.其逻辑上和物理上都是连续的. 问题引入:一个数组放在这,我们如何才能自己不去数,让程序自己进行计数? 答:在引入变量,每次放一个元素就更新一次.(如下图,为问题的示意) 也就是说顺序表的底层

  • Java 数据结构之删除链表中重复的结点

    目录 解析一:(不提倡) 解析二:(正解) 核心考点:链表操作,临界条件检查,特殊情况处理 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 解析一:(不提倡) 解决该问题较简单,且在写代码时不易出错的做法如下: 遍历一遍链表,记录重复结点的结点值. 再遍历一遍链表,逐个删除重复结点. 动图演示: 该方法需要遍历两遍链表,且需要开辟额外的内存空间存储重复结点的结点值,所以一般不提倡. /* struct ListNode { int val; st

  • Java数据结构与算法学习之双向链表

    目录 双向链表的储存结构示意图 双向链表的初始化结构 1.双向链表的结点 2.双向链表的头结点 3.总代码 双向链表中的指定文件插入元素  1.插入的为第一个位置 2.其他位置插入 总代码 双向链表的删除 1.删除第一个元素 2.删除其他位置元素 总代码 双向链表的储存结构示意图 双向链表的初始化结构 1.双向链表的结点 代码实现 //双向链表的结点,包含一个数据域,两个指针域 typedef struct DoublyNode { ElementType date; //数据域 struct

  • Java 精炼解读数据结构的链表的概念与实现

    目录 前言: 一.什么是链表 链表的概念 链表的结构 链表如何存储数据 链表的实现   穷举法创建链表 打印链表 查找是否包含关键字key是否在单链表当中  得到单链表的长度: 头插法 尾插法 任意位置插入,第一个数据节点为0号下标 删除第一次出现关键字为key的节点 删除所有值为key的节点 总结: 前言: 顺序表的问题及思考 1. 顺序表中间/头部的插入删除,时间复杂度为O(N) 2. 增容需要申请新空间,拷贝数据,释放旧空间.会有不小的消耗. 3. 增容一般是呈2倍的增长,势必会有一定的空

  • Java 精炼解读数据结构的顺序表如何操作

    目录 前言 一.什么是顺序表 顺序表的概念及结构 创建顺序表 获取顺序表长度 在pos位置新增元素 判定是否包含某个元素 查找某个元素对应的位置 获取pos位置的元素 给pos位置的元素设为value 删除你想要删除的元素 总结: 前言 线性表(linear list)是n个具有相同特性的数据元素的有限序列. 线性表是一种在实际中广泛使用的数据结构,常见 的线性表:顺序表.链表.栈.队列.字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线.但是在物理结构上并不一定是连续的,线性表在物

  • Java 精炼解读数据结构逻辑控制

    目录 一.顺序结构 二.分支结构 switch语句  三.循环结构 3.1while循环  3.2break 3.3continue  3.4for循环  3.5dowhile循环(选学)  总结: 一.顺序结构 程序的执行和代码的执行顺序有关,如果调整代码的书写顺序, 则执行顺序也发生变化 二.分支结构 基本语法形式1: if(布尔表达式){     //条件满足时执行代码 } 基本语法形式2 if(布尔表达式){     //条件满足时执行代码 }else{     //条件不满足时执行代码

  • Java 精炼解读递归的概念与使用

    目录 一.递归的概念 1.什么是递归? 2.递归讲解 二.递归的使用  总结: 一.递归的概念 1.什么是递归? 递归就是:方法自己调用方法的过程. 使用递归有两个前提条件: 1.有一个趋近与终止的条件. 2.自己调用自己 . 如何实现递归? 最重要的方式是:实现递归,需要去推导出一个递推公式. 思考递归的方式:横向思考,根据递推公式来思考. 代码的执行:是纵向执行. 2.递归讲解 首先看下面代码: public class TestDemo { public static void func(

  • Java 精炼解读类和对象原理

    面向对象.面向过程 什么是类? 什么是对象? 这是非常抽象的两个概念!!!!!!!! 在说清楚类和对象的概念之前,给大家讲一下什么是面向对象.面向过程,以此来推出我们类和对象的概念. 面向过程:以洗衣服为例:拿盆.放水.放衣服.放洗衣粉.手搓.换水.拧干.晾衣服,这个过程就是面向过程.  面向对象:以洗衣服为例:人把衣服放进洗衣机,倒入洗衣粉,洗完晾干,不需要关心洗衣服整个过程是怎么完成的,只需要找对象,创建对象,使用对象.在好比我们使用toString函数,我们并不关心toString函数具体

  • Java 精炼解读时间复杂度与空间复杂度

    目录 前言: 一.算法效率 二.时间复杂度 1.时间复杂度概念 2.大O的渐进表示法 计算时间复杂度 三.空间复杂度 总结: 前言: 所谓的复杂度就是衡量算法的效率,衡量算发效率又分为两种,一种叫做时间复杂度,一种叫做空间复杂度. 一.算法效率 算法效率分析分为两种:第一种是时间效率,第二种是空间效率.时间效率被称为时间复杂度,而空间效率被 称作空间复杂度. 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额 外空间,在计算机发展的早期,计算机的存储容量很小.所以对

  • Java 精炼解读方法的定义与使用

    目录 一.方法的基本用法 1.1什么是方法(method) 1.2方法定义语法  1.3方法的开辟  二.方法的重载  三.方法的使用  一.方法的基本用法 1.1 什么是方法(method) 方法就是一个代码片段. 类似于 C 语言中的 "函数".方法可以把它理解为一个功能,这个功能是可以重复使用的. 1.2 方法定义语法  目前来说写任何方法的时候都写成: pubiic static 返回值 返回名称(形式参数列表){ 函数体/方法体 } 代码举例:求1-n的和 /** * 求我们

  • Java数据结构之链表的增删查改详解

    一.链表的概念和结构 1.1 链表的概念 简单来说链表是物理上不一定连续,但是逻辑上一定连续的一种数据结构 1.2 链表的分类 实际中链表的结构非常多样,以下情况组合起来就有8种链表结构. 单向和双向,带头和不带头,循环和非循环.排列组合和会有8种. 但我这只是实现两种比较难的链表,理解之后其它6种就比较简单了 1.单向不带头非循环链表 2.双向不带头非循环链表 二.单向不带头非循环链表 2.1 创建节点类型 我们创建了一个 ListNode 类为节点类型,里面有两个成员变量,val用来存储数值

  • Java数据结构之链表(动力节点之Java学院整理)

    单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) find:查找包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N) remove:删除包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N) public class LinkedList { private class Data{ private Object obj; private Data next =

  • java 数据结构单链表的实现

    java 数据结构单链表的实现 单链表实现链表的打印及元素删除操作,链表的实现主要是next属性的定义,将一堆节点关联起来的.实现简单的链表如下: public class LinkNode { private int value; private LinkNode next; public LinkNode(int x) { value = x; } public LinkNode getNext(){ return next; } public void setNext(LinkNode n

随机推荐