数据结构-链表

链表的概念

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

链表结构非常多样,总共分为8种

1.单向或者双向

2.带头或者不带头

链表的头部也称为哨兵位 ,一般不存储数据,一直作为头部

3.循环或者非循环

我们一般掌握:

无头单向非循环链表(单链表):一般不会单独用来存数据,实际中是作为其他数据结构的子结构

无头双向非循环链表(双链表) :在Java的集合框架库中LinkedList底层实现就是无头双向循环链表

LinkedList的使用

LinkedList的底层是双向链表结构

在集合框架中,LinkedList也实现了List接口

注意:

LinkedList不支持随机访问且任意位置插入和删除元素的效率比较高,时间复杂度为O(1)

LinkedList的构造

java 复制代码
LinkedList<Integer> list=new LinkedList<>();
List<Integer> list2=new LinkedList<>();

LinkedList常用方法

remove会返回被删除的元素 ,subList截取的是元素的地址 ,也就是说通过返回值仍可以对原链表进行修改

LinkedList的遍历

java 复制代码
  // foreach遍历
    for (int e:list) {
        System.out.print(e + " ");
   }
    System.out.println();
    // 使用迭代器遍历---正向遍历
    ListIterator<Integer> it = list.listIterator();
    while(it.hasNext()){
        System.out.print(it.next()+ " ");
   }
    System.out.println();
    // 使用反向迭代器---反向遍历
    ListIterator<Integer> rit = list.listIterator(list.size());
    while (rit.hasPrevious()){
        System.out.print(rit.previous() +" ");
   }
    System.out.println();
}

ArrayList和LinkedList的区别

栈和队列

栈

栈:一种特殊的线性表 ,其只允许在固定的一端进行插入和删除元素 。进行数据插入和删除操作的一端是栈顶,另一端是栈底。栈中的数据遵循后进先出的LIFO原则

压栈:栈的插入操作叫做进栈/压栈/入栈,数据在栈顶

出栈:栈的删除操作,出的数据在栈顶

栈的使用

LinkedList也可以当作栈来使用,方法均是通用的

栈的应用场景

改变元素的序列

将递归转化为循环

比如:对链表进行逆序打印

递归:

java 复制代码
  public static void Print1(MyLinkedList.ListNode head){
        if(head.next!=null){
             Print1(head.next);
        }
        System.out.print(head.data+" ");

    }

循环:

java 复制代码
    public static void Print2(MyLinkedList.ListNode head){
        Stack<MyLinkedList.ListNode> stack=new Stack<>();
        while(head!=null){
            stack.push(head);
            head=head.next;
        }
        while(!stack.empty()){
            System.out.print(stack.pop().data+" ");
        }
        System.out.println();
    }

栈:一种数据结构

栈帧:运行方法时给方法开辟的内存

虚拟机栈:内存

队列

只允许在一端进行插入数据操作,在另一端进行删除操作的特殊线性表,队列是先进先出 ,入队列: 在进行插入 操作的一端称为队尾 ,出队列: 进行删除 操作的一端称为队头。

队列的使用

在Java中,Queue是一个接口 ,底层通过链表实现

注意: Queue是一个接口,在实例化时必须先实例化LinkedList的对象 ,因为LinkedList实现了Queue的接口。

循环队列

在实际中我们还会使用到循环列队,比如操作系统课程讲解生产者和消费者模型的时候就会使用循环列队,环形列队通常使用数组实现

1.数组下标往后时 index=(index+offset)%array.length

2.数组下标往前遍历时,使用index=(index+array.length-offset)%array.length

如何区分空和满:

1.通过size属性记录

2.保留一个位置

3.使用标记

双端队列

双端队列是指允许两端都可以进行入队和出队操作。

Deque是一个接口,使用时必须创建LinkedList对象

栈和队列都可以通过此接口来实现

java 复制代码
Deque<Integer> stack = new ArrayDeque<>();//双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现
相关推荐
m4Rk_9 小时前
【论文阅读】Agent 记忆机制(83):Inside Out——用可演化 PersonaTree 构建 Agent 的核心长期记忆
论文阅读·人工智能·学习·开源·github
不会就选b9 小时前
算法日常・每日刷题--<贪心>25
数据结构·算法
EatFan10 小时前
Spring Boot 4 落地观察:从 yudao-cloud、matecloud、JPower 看国产脚手架的升级路线与迁移清单
java·spring boot·后端·spring cloud·微服务·后端开发·jdk 21
Maiko Star10 小时前
* LangChain 提示词模板详解:ChatPromptTemplate 的使用与高级特性
java·人工智能·langchain
鬓戈10 小时前
Rust 语言与 AI 应用生态调研及学习路径
人工智能·学习·rust
传奇开心果编程10 小时前
【SwiftUI娓娓道来】第3课:让界面活起来——交互与动画指南
学习·macos·ui·ios·swiftui·swift
xian_wwq11 小时前
【学习笔记】等保合规安全基线核查实战
笔记·学习
传奇开心果编程11 小时前
【Jetpack Compose进阶学与练】第14课:系列收尾复习总结;Compose项目常见坑点汇总;学习路线与后续学习方向
android·学习·ui·kotlin·android jetpack
yangmu320312 小时前
发动机是怎么把油变成动力的:四冲程内燃机原理拆解
学习
m4Rk_12 小时前
【论文阅读】Agent 记忆机制(81):EMR——用情景记忆避免 Agent 在多步推理中反复绕圈
论文阅读·人工智能·学习·开源·github