数据结构——链表(java)

这篇具有很好参考价值的文章主要介绍了数据结构——链表(java)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

链表

1. 基本介绍

1.1 定义

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

如图所示:
java 链表,数据结构,数据结构,链表,java

1.2 链表分类

单向、双向;带头、不带头;循环、非循环
重点:单向不带头非循环、双向不带头非循环(集合类底层)

如图:单项带头非循环链表结构
java 链表,数据结构,数据结构,链表,java
如图:单向带头循环链表结构
java 链表,数据结构,数据结构,链表,java
如图:双向不带头循环链表结构
java 链表,数据结构,数据结构,链表,java

3.不带头非循环单链表CURD

代码展示:

package demo3;

/**
 * @author zq
 * 不带头非循环单链表相关操作
 */
public class MySingleList {

    class Node {
        public int val;//存储数据
        public Node next;//存储下一个节点地址

        public Node(int val) {
            //不知道下一个节点位置,只需要val
            this.val = val;
        }

    }
    public Node head;//代表当前头节点的引用

    //遍历链表
        //创建链表
        public void createLink(){
            Node node1 = new Node(12);
            Node node2 = new Node(45);
            Node node3 = new Node(23);
            Node node4 = new Node(90);

            node1.next = node2;
            node2.next = node3;
            node3.next = node4;
            head = node1;
        }
        //遍历链表,利用head遍历链表
        public void display() {
            while (head != null){
                System.out.println(head.val);
                head = head.next;
            }
        }
        //查找是否包含关键字key是否在单链表当中
        public boolean contains(int key){
            Node cur = head;
            while (cur != null){
                if (cur.val == key){
                    return true;
                }
                cur = cur.next;
            }
            return false;
        }
        //头插法
        public void addFirst(int data){
            Node node = new Node(data);
            node.next = head;
            head = node;
        }

        //尾插法,需判断head是否为空
        public void addLast(int data){
            Node node = new Node(data);
            if (head == null) {
                head = node;
                return;
            }
                Node cur = head;
                while (cur.next != null) {
                    cur = cur.next;
                }
                cur.next = node;
            }




        //任意位置插入,第一个数据节点为0号下标
        public void addIndex(int index,int data){
            checkindex(index);
            if (index == 0){
                addFirst(data);
                return;
            }
            if (index == size()){
                addLast(data);
                return;
            }

            Node cur = findIndexSubOne(index);
            Node node = new Node(data);
            node.next = cur.next;
            cur.next = node;



        }
        /*
        找到index-1处的节点
         */
        private Node findIndexSubOne(int index){
            Node cur = head;
            int count = 0;
            while (count != index -1 ){
                cur = cur.next;
                count++;
            }
            return cur;

        }
        private void checkindex(int index){
            if (index<0||index>size()){
                throw new IndexOutOfException("index位置不合法");
            }
        }

        //删除第一次出现关键字为key的节点
        public void remove(int key){
            if (head.val == key){
                head = head.next;
                return;
            }
          Node cur = searchPrev(key);
            if (cur == null){
                return;
            }
          cur.next = cur.next.next;
        }

        //删除所有值为key的节点
        public void removeAllKey(int key){

            if (head == null){
                return;
            }
            //如果前俩个节点值均为key时。
            // 或者用if放到最后,直接删掉漏掉的节点
            while (head.val==key){
                head = head.next;
            }
            Node prev = head;
            Node cur = head.next;
            while (cur != null){
                if (cur.val == key){
                    prev.next = cur.next;
                    cur = cur.next;
                }else{
                    prev = cur;
                    cur = cur.next;
                }
            }

        }
        //找到关键字key的前一个节点
    private Node searchPrev(int key){
            if (head== null){
                return null;//链表为空时
            }
            Node cur = head;
            while (cur.next!= null){
                if (cur.next.val == key){
                    return cur;
                }
                cur = cur.next;
            }
            return null;//没有需要删除的节点
    }

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

        /*
        保证列表中每一个节点都被回收
         */
        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;
        }
}


4.不带头非循环双向链表CURD

代码展示:文章来源地址https://www.toymoban.com/news/detail-705671.html

package demo4;

import demo3.MySingleList;

import java.util.List;

/**
 * @author zq
 * LinkedList的实现
 * 双向链表
 */
public class MyLinkedList {
    static class ListNode{
        ListNode prev;
        ListNode next;
        int val;

        public ListNode(int val) {
            //不知道下一个节点位置,只需要val
            this.val = val;
        }

    }
    public MyLinkedList.ListNode head;//代表当前头节点的引用
    public MyLinkedList.ListNode last;//代表最后节点的引用


    //头插法
    public void addFirst(int data){
        ListNode node = new ListNode(data);
        if (head == null) {
            head = node;
            last = node;
        }else{
            node.next = head;
            node.prev = null;
            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;
            node.next = null;
            last = node;
        }

    }
    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index,int data){
        ListNode node = new ListNode(data);
        checkindex(index);
        if (index==0){
            addFirst(data);
            return;
        }
        if (index==size()){
            addLast(data);
            return;
        }
        ListNode cur = findIndex(index);
        node.next = cur;
        cur.prev.next = node;
        node.prev = cur.prev;
        cur.prev = node;



    }
    //判断插入位置是否合法
    private void checkindex(int index){
        if (index<0||index>size()){
            throw new IndexOutOfException("index位置不合法");
        }
    }
    /*
    找到index处的节点
         */
    private ListNode findIndex(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{
                    //中间,尾巴都能用此行代码。
                    cur.prev.next = cur.next;
                    if (cur.next != null){
                        //不是尾巴节点
                        cur.next.prev = cur.prev;
                    }else {
                        last = cur.prev;
                    }
                }
                return;
            }
            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{
                    //中间,尾巴都能用此行代码。
                    cur.prev.next = cur.next;
                    if (cur.next != null){
                        //不是尾巴节点
                        cur.next.prev = cur.prev;
                    }else {
                        last = cur.prev;
                    }
                }
            }
            cur = cur.next;
        }


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

        return len;
    }
    public void display(){
        ListNode cur = head;
       while (cur !=null){
           System.out.print(cur.val + " ");
           cur = cur.next;
       }
    }
    public void clear(){
        head = null;
    }
}

到了这里,关于数据结构——链表(java)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java数据结构】顺序表、队列、栈、链表、哈希表

    是一个有类型参数(type parameter)的范型表(generic class) 能够自动调整容量,并且不需要写额外的代码 存放数据使用数组但是可以编写一些额外的操作来强化为线性表,底层依然采用顺序存储实现的线性表,称为顺序表 创建 常见操作 一旦确认数组列表大小恒定,不再发生

    2024年02月02日
    浏览(30)
  • 【Java--数据结构】链表经典OJ题详解(上)

    欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 谈谈头插、头删、尾插、头插的时间复杂度 反转一个单链表  链表的中间结点 返回倒数第k个结点 合并两个链表 头插和头删的时间复杂度为O(1), 尾插和尾删的时间复杂度为O(n) (因为尾插和

    2024年04月27日
    浏览(23)
  • Java 数据结构篇-用链表、数组实现队列(数组实现:循环队列)

    🔥博客主页: 【 小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍   文章目录         1.0 队列的说明         1.1 队列的几种常用操作         2.0 使用链表实现队列说明         2.1 链表实现队列         2.2 链表实现队列 - 入栈操作         2.3 链表实现队

    2024年02月05日
    浏览(27)
  • Java常见的数据结构:栈、队列、数组、链表、二叉树、二叉查找树、平衡二叉树、红黑树

    数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。 通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率 栈 队列 数组 链表 二叉树 二叉查找树 平衡二叉树 红黑树... 后进先出,先进后出 数据进入栈模型的过程称为

    2024年02月07日
    浏览(28)
  • 【数据结构】线性表 ⑤ ( 双循环链表 | 双循环链表特点 | 双循环链表插入操作处理 | 代码示例 - 使用 Java 实现 双循环链表 )

    \\\" 双循环链表 \\\" 是 在 单循环链表 的基础上 , 在每个 节点 中 , 新增一个 指针 , 指向 该节点 的 前驱节点 ; 双向循环链表 每个 节点 都包含 数据 和 两个指针 , 一个指针指向前一个节点 , 一个指针指向后一个节点 ; 与 单循环链表相比 , 双循环链表 可以在两个方向上遍历整个链

    2024年02月13日
    浏览(26)
  • 数据结构-链表结构-双向链表

    双向链表也叫双链表,与单向链表不同的是,每一个节点有三个区域组成:两个指针域,一个数据域 前一个指针域:存储前驱节点的内存地址 后一个指针域:存储后继节点的内存地址 数据域:存储节点数据 以下就是双向链表的最基本单位 节点的前指针域指向前驱,后指针

    2024年02月04日
    浏览(34)
  • <数据结构> 链表 - 链表的概念及结构

    概念: 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的 逻辑顺序 是通过链表中的 指针链接 次序实现的 1、链表由一系列结点(链表中每一个元素称为结点)组成。 2、结点可以在运行时动态(malloc)生成。 3、每个结点包括两个部分:一个是存储数据元素的

    2023年04月09日
    浏览(28)
  • 【数据结构-链表-01】反转链表

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月10日
    浏览(28)
  • 数据结构——线性数据结构(数组,链表,栈,队列)

    数组(Array) 是一种很常见的数据结构。它由相同类型的元素(element)组成,并且是使用一块连续的内存来存储。 我们直接可以利用元素的索引(index)可以计算出该元素对应的存储地址。 数组的特点是: 提供随机访问 并且容量有限。 2.1. 链表简介 链表(LinkedList) 虽然是

    2024年02月11日
    浏览(30)
  • 【数据结构】详解链表结构

    上篇博客已经介绍了顺序表的实现:【数据结构】详解顺序表。最后在里面也谈及了顺序表结构的缺陷,即 效率低,空间浪费 等等问题,那么为了解决这些问题,于是乎我们引入了链表的概念,下面将对链表结构进行讲解 首先肯定会问,到底什么是链表? 链表的概念 : 链

    2024年02月05日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包