【数据结构】LinkedList模拟实现与简单使用
创始人
2024-05-06 15:18:29
0

文章目录

  • 模拟实现LinkedList
  • LinkedList的简单使用
    • LinkedList的一些方法
    • LinkedList的遍历
  • 简单对比一下LinkedList和ArrayList

模拟实现LinkedList

在上一篇的博客中,我们讲解了链表的基础知识,并且模拟实现了一个无头单向不循环链表,链表的基础知识讲解,大家有兴趣可以去看一下。Java给我们提供的链表其实是一个双向的链表,那今天我们就完善一下我们的LinkedList的模拟实现。
双向链表的每个节点需要有一个前驱:用来访问前一个结点,和一个后继:用来访问后一个结点,还需要记录第一个结点head,和最后一一个结点last。

public class MyLinkedList2 {static class LinkNode {public int val;//用于储存数据public LinkNode next;//用于找到下一个结点public LinkNode prev;//找到前一个节点public LinkNode(int val) {this.val = val;}}public LinkNode head;//记录第一个节点public LinkNode last;//记录最后一个节点}

有一些方法是不需要进行更改的我就不在进行讲解了,想了解可以看上一篇文章。这里我们只讲解一些需要用到prev的方法,例如头插法

 public void addFirst(int data){LinkNode newNode = new LinkNode(data);if(head == null) {head = newNode;last = newNode;}else {newNode.next = head;head.prev = newNode;head = newNode;}}

在这里插入图片描述
这样就完成了我们的头插法。

尾插法

 public void addLast(int data){LinkNode newNode = new LinkNode(data);if(head == null) {head = newNode;last = newNode;}else {last.next = newNode;newNode.prev = last;last = newNode;}}

在双向链表中尾插法的时间复杂度变为了O(1),不需要在遍历链表找到最后一个元素进行尾插,我们直接找到记录最后一个节点的last节点就可以进行尾插了。

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

    public void addIndex(int index,int data){try {checkIndex(index);} catch (ListIndexException ex) {ex.printStackTrace();}if(index == 0) {addFirst(data);return ;}if(index == size()) {addLast(data);return ;}LinkNode tmp = FindIndexNode(index);//直接找到该位置的元素就可以不需要找到前一个元素LinkNode newNode = new LinkNode(data);newNode.next = tmp;newNode.prev = tmp.prev;tmp.prev.next = newNode;tmp.prev = newNode;}private LinkNode FindIndexNode(int index) {//找到index位置的结点LinkNode cur = head;while (index != 0) {cur = cur.next;index--;}return cur;}private void checkIndex(int index) throws ListIndexException{if(index < 0 || index > size()) {throw new ListIndexException("插入下标错误");}}

在任意位置插入元素,也不需要向单向链表一样找到要插入位置的前一个节点,我们直接找到要插入位置的节点通过prev就可以访问前一个结点。

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

 public void remove(int key){LinkNode 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 = last.prev;}}return ;}cur = cur.next;}}

删除所有值为key的节点

    public void removeAllKey(int key){LinkNode 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 = last.prev;}}//return ; - 去掉return就实现了}cur = cur.next;}}

这两个方法在双向链表中逻辑是一样的,我们不需要像单向链表一样找到需要删除结点的前一个结点,因为我们有prev可以访问到前一个结点,我们只需要对删除结点是否是头尾进行判断就可以了。
在这里插入图片描述
上面图画的是最复杂的情况,如果为头节点和尾结点,将head或者last进行一些改变就可以了,这里就不在画图讲解了。

清空链表

 public void clear() {LinkNode cur = head;while (cur != null) {LinkNode curNext = cur.next;cur.next = null;cur.prev = null;cur = curNext;}head = null;last = null;}

与单向链表相比我们就不能那么暴力了,当然我们也可以将headlast都置为空,但还是太过暴力,我们还是遍历链表将所有结点的nextprev都置为null,这样我们就完善了LinkedList的实现。

LinkedList的简单使用

LinkedList的一些方法

方法功能
boolean add(E e)尾插 e
void add(int index, E element)将 e 插入到 index 位置
boolean addAll(Collection c)尾插 c 中的元素
E remove(int index)删除 index 位置元素
boolean remove(Object o)删除遇到的第一个 o
E get(int index)获取下标 index 位置元素
E set(int index, E element)将下标 index 位置元素设置为 element
void clear()清空
boolean contains(Object o)判断 o 是否在线性表中
int indexOf(Object o)返回第一个 o 所在下标
int lastIndexOf(Object o)返回最后一个 o 的下标
List subList(int fromIndex, int toIndex)截取部分 list
public static void main(String[] args) {LinkedList list = new LinkedList<>();list.add(1);list.add(2);list.add(3);for(Integer num : list) {System.out.print(num + " ");}}

我们创建一个LinkedList的对象调用他的add方法添加一些结点,并且通过foreach的形式遍历链表,这样我们就打印出了链表中的内容,当然我们还可以使用其他的方法对链表进行一些操作,大家可以自己尝试一下。

在这里插入图片描述

LinkedList的遍历

1、foreach遍历

 public static void main(String[] args) {LinkedList list = new LinkedList<>();list.add(1);list.add(2);list.add(3);for(Integer num : list) {System.out.print(num + " ");}System.out.println();}

2、迭代器正向遍历

 public static void main(String[] args) {LinkedList list = new LinkedList<>();list.add(1);list.add(2);list.add(3);ListIterator it = list.listIterator();while(it.hasNext()) {System.out.print(it.next() + " ");}System.out.println();}

3、迭代器反向遍历

 public static void main(String[] args) {LinkedList list = new LinkedList<>();list.add(1);list.add(2);list.add(3);ListIterator it2 = list.listIterator(list.size());while(it2.hasPrevious()) {System.out.print(it2.previous() + " ");}System.out.println();}

在这里插入图片描述
通过这三种方法我们就可以对LinkedList进行遍历。

简单对比一下LinkedList和ArrayList

学完了这两种数据结构之后,这两种数据结构的使用场景是怎样的呢?二者有什么区别呢?我们来简单总结一下。

LinkedListArrayList
逻辑上是连续的但是物理上不一定连续物理上一定连续
随机访问的时间复杂度为O(N)随机访问时时间复杂度为O(1)
头插时时间复杂度为O(1)头插时时间复杂度为O(N)
没有容量的概念有容量的概念,需要扩容

所以当我们的业务需求为:需要频繁访问数据时,我们可以用ArrayList顺序表来处理数据,当需求为:频繁的插入删除数据时,我们可以使用LinkedList链表来处理数据

相关内容

热门资讯

安卓系统计划软件推荐,精选计划... 你有没有发现,手机里的安卓系统越来越智能了?这不,最近我可是挖到了一些超棒的安卓计划软件,它们不仅能...
收钱吧安卓系统插件,便捷支付新... 你有没有发现,现在的生活越来越离不开手机了?手机里装满了各种应用,而今天我要跟你聊聊一个特别实用的工...
鸿蒙系统是否还属于安卓,独立于... 你有没有想过,那个在我们手机上默默无闻的鸿蒙系统,它到底是不是安卓的“亲戚”呢?这个问题,估计不少手...
安卓系统手机用什么钱包,轻松管... 你有没有想过,你的安卓系统手机里装了那么多应用,但最离不开的,可能就是那个小小的钱包了。没错,就是那...
安卓系统能玩部落冲突吗,部落冲... 你有没有想过,安卓系统上的手机,是不是也能玩那款风靡全球的《部落冲突》呢?这款游戏自从推出以来,就吸...
智能机器人安卓系统,引领未来智... 你知道吗?在科技飞速发展的今天,智能机器人已经不再是科幻电影里的专属了。它们正悄悄地走进我们的生活,...
华为win10系统改装安卓系统... 你有没有想过,你的华为笔记本电脑里的Windows 10系统,能不能来个华丽变身,变成安卓系统呢?这...
旧电脑上安什么安卓系统,适配不... 你那台旧电脑是不是已经闲置好久了?别让它默默无闻地躺在角落里,给它来个华丽变身吧!今天,就让我来告诉...
安卓app语言跟随系统,随系统... 你知道吗?在手机世界里,有一个神奇的小功能,它就像你的贴身翻译官,无论你走到哪里,都能帮你轻松应对各...
惠城安卓系统降级在哪,揭秘降级... 你有没有遇到过手机系统升级后,发现新系统让你头疼不已,想回到那个熟悉的安卓系统呢?别急,今天就来告诉...
阿里云系统转安卓,揭秘安卓平台... 你知道吗?最近有个大动作在互联网圈里引起了不小的波澜,那就是阿里云系统竟然要转战安卓阵营了!这可不是...
安卓系统有最美壁纸么,探寻最美... 哦,亲爱的安卓用户,你是否曾在某个午后,百无聊赖地翻看着手机,突然被那一张张壁纸惊艳了眼眸?是的,我...
安卓系统采用Linux操作系统... 你知道吗?安卓系统,这个在我们手机上无处不在的小家伙,它的心脏竟然是Linux操作系统内核!是不是觉...
安卓原生平板通用系统,探索安卓... 你有没有发现,现在市面上平板电脑的品牌和型号真是五花八门,让人挑花了眼?不过,你知道吗?在众多安卓平...
小米1系统是安卓几,搭载安卓几... 你有没有想过,你的小米手机里那个熟悉的系统,其实是基于安卓的哦!没错,就是那个全球最流行的手机操作系...
可以安装安卓系统的相机,智能摄... 你有没有想过,一台相机不仅能拍出美美的照片,还能像智能手机一样,玩转各种应用?没错,现在市面上就有这...
安卓系统gps定位不准,安卓G... 你是不是也遇到过这种情况?手机里的安卓系统GPS定位总是不准,让人头疼不已。有时候,你明明就在家附近...
电信机顶盒装安卓系统,开启智能... 你有没有想过,家里的电信机顶盒其实也可以装上安卓系统呢?听起来是不是有点不可思议?别急,让我带你一步...
安卓系统可以做苹果桌面,打造个... 你知道吗?现在科技的发展真是让人眼花缭乱,竟然有人想出了安卓系统可以做苹果桌面的神奇想法!是不是觉得...
安卓系统自带的网页,功能与特色... 你有没有发现,每次打开安卓手机,那熟悉的系统界面里总有一个默默无闻的小家伙——安卓系统自带的网页浏览...