【数据结构】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链表来处理数据

相关内容

热门资讯

安卓系统短消息提醒,安卓系统短... 你有没有发现,手机里的短消息提醒功能有时候就像一个贴心的管家,有时候又像个爱闹腾的小孩子?今天,咱们...
安卓系统如何跳过密码,安卓系统... 你是不是也和我一样,有时候手机锁屏密码设置得太复杂,每次解锁都要费好大一番力气?别急,今天就来教你怎...
鸿蒙系统功能与安卓,功能对比与... 你知道吗?最近手机圈里可是热闹非凡呢!华为的新操作系统鸿蒙系统(HarmonyOS)一经推出,就引发...
安卓系统卡苹果系统不卡,揭秘两... 你有没有发现,身边的朋友都在争论安卓系统和苹果系统哪个更好?其实,这个问题就像是在问谁家的孩子更聪明...
安卓系统卡解决了吗,安卓系统卡... 你有没有遇到过安卓手机卡顿的问题?是不是每次打开应用都感觉像蜗牛爬行?别急,今天就来聊聊这个让人头疼...
华为安卓系统下载软件,畅享海量... 你有没有想过,手机里的系统就像是我们的大脑,而下载的软件就像是大脑里的各种功能?今天,就让我带你一起...
平板安卓7系统好吗,体验流畅与... 你有没有想过,你的平板电脑的安卓7系统到底怎么样呢?是不是觉得它既熟悉又有点陌生?别急,今天咱们就来...
鸿蒙系统和安卓10,跨时代操作... 你知道吗?最近科技圈可是炸开了锅,因为华为的新操作系统鸿蒙系统横空出世,而且它竟然和安卓10杠上了!...
苹果安卓和鸿蒙系统,三大操作系... 你有没有发现,现在的手机市场就像是一场精彩纷呈的武林大会,各路英雄齐聚一堂,各显神通?没错,说的就是...
鸿蒙怎么还原安卓系统,系统还原... 你是不是也和我一样,对鸿蒙系统里的安卓应用情有独钟呢?最近,不少小伙伴都在问,鸿蒙怎么还原安卓系统?...
荣耀10改回安卓系统,重拾纯净... 你有没有想过,你的荣耀10手机,曾经那般风光无限,如今却想要改回安卓系统呢?这可不是一件小事,得好好...
华为安卓系统设置权限,深度解析... 亲爱的手机控们,你是否曾为手机里那些层出不穷的权限请求而头疼?别急,今天就来给你详细解析一下华为安卓...
安卓刷系统的软件,探索系统升级... 你有没有遇到过手机卡顿、系统老化的问题?别急,今天就来给你安利几款超好用的安卓刷系统软件,让你的手机...
安卓系统投影怎么升级,轻松实现... 你有没有发现,你的安卓系统投影最近有点儿慢吞吞的,是不是也想给它来个升级,让它焕发新生呢?别急,今天...
安卓手机系统怎样加速,享受流畅... 你有没有发现,你的安卓手机最近变得有点“慢吞吞”的?别急,别急,今天就来给你支几招,让你的安卓手机瞬...
安卓系统怎么安装的,安卓系统安... 你有没有想过,你的安卓手机里那些神奇的APP是怎么来的呢?是不是觉得安装个APP就像变魔术一样简单?...
安卓系统下儿童编程,开启编程启... 你有没有想过,在这个科技飞速发展的时代,连小朋友也开始学习编程了呢?没错,就是那个在安卓系统下,孩子...
微信安卓系统转苹果系统,轻松实... 你有没有想过,从微信安卓系统转到苹果系统,这中间的转换过程,就像是一场说走就走的旅行,充满了未知和惊...
如何刷安卓8.0系统,安卓8.... 你有没有想过,让你的安卓手机升级到最新的8.0系统,让它焕发出全新的活力呢?别急,今天我就来给你详细...
安卓系统里查看路由,安卓系统下... 你是不是也和我一样,对家里的无线网络充满了好奇?想知道安卓手机里怎么查看路由器信息?那就跟着我一起探...