数据结构-java中链表的存储原理及使用方式

news/2024/8/26 9:51:00 标签: 数据结构, 链表

目录

链表(线性表的链式存储)

代码实例:(链表构建,头插+尾插)

LinkedList

LinkedList的使用:

1、构造方法

 2、操作方法

LinkedList 和 ArrayList 的区别


链表(线性表的链式存储)

它可以不断扩容,无固定长度

每一个节点都是由value和next构成

有两种插入的方式:头插法尾插法

代码实例:(链表构建,头插+尾插)

public class Listnode {
    public int value;
    public Listnode next; //指针
    public Listnode(int n) {
        this.value=n;
    }
public class Linklist {
    //定义头指针
    Listnode head;

    //头插法
    public void startAdd(int n) {
        Listnode listnode=new Listnode(n);
        listnode.next=head;//新节点的next是原来的首节点
        head=listnode;//头结点指向新节点实现头插法
    }
    //尾插法
    public void endAdd(int n) {
        Listnode listnode=new Listnode(n);
        //判断头结点是否为空,空就通过值传递把新节点传给头节点
        if(head==null) {
            head=listnode;
            return;
        }
        //头结点不是空,则往下遍历,一直找到尾结点,此时temp就指向尾结点
        Listnode temp=head;
        while(temp.next!=null) {
            temp=temp.next;
        }
        //尾结点的后面插入新节点
        temp.next=listnode;
    }

    //把添加的值打印的方法
    public void printLink() {
        Listnode temp=head;
        while(temp!=null) {
            System.out.print(temp.value+"->");
            temp=temp.next;
        }
    }
}

测试类:

public class Test {
    public static void main(String[] args) {
        Linklist linklist=new Linklist();
        linklist.endAdd(1);
        linklist.endAdd(2);
        linklist.startAdd(0);
        linklist.startAdd(-1);
        linklist.startAdd(-2);
        linklist.printLink();
    }
}

LinkedList

在Java中,LinkedList(链表)是Java提供的一个实现了List接口的类。是基于双向链表结构实现的

LinkedList的使用:

1、构造方法

1、LinkedList():创建一个空的LinkedList对象。

LinkedList<String> list = new LinkedList<>();

2、LinkedList(Collection<? extends E> c):创建一个包含指定集合中的元素的LinkedList对象。集合中的元素将按照迭代器返回的顺序添加到LinkedList中。

List<String> collection = new ArrayList<>();
collection.add("Element 1");
collection.add("Element 2");
LinkedList<String> list = new LinkedList<>(collection);

3、LinkedList(LinkedList<? extends E> c):创建一个包含指定LinkedList中的元素的LinkedList对象。指定LinkedList中的元素将按照迭代器返回的顺序添加到新的LinkedList中。

LinkedList<String> originalList = new LinkedList<>();
originalList.add("Element 1");
originalList.add("Element 2");
LinkedList<String> newList = new LinkedList<>(originalList);

 2、操作方法

1、添加元素:

  • add(E element):在链表末尾添加一个元素。
  • addFirst(E element):在链表开头添加一个元素。
  • addLast(E element):在链表末尾添加一个元素。
LinkedList<String> list = new LinkedList<>();
list.add("Element 1");
list.addFirst("Element 0");
list.addLast("Element 2");

2、获取元素:

  • get(int index):获取指定位置的元素。
  • getFirst():获取链表的第一个元素。
  • getLast():获取链表的最后一个元素。
LinkedList<String> list = new LinkedList<>();
list.add("Element 1");
list.add("Element 2");
String element = list.get(0);
String firstElement = list.getFirst();
String lastElement = list.getLast();

3、删除元素:

  • remove(int index):删除指定位置的元素。
  • removeFirst():删除链表的第一个元素。
  • removeLast():删除链表的最后一个元素。
LinkedList<String> list = new LinkedList<>();
list.add("Element 1");
list.add("Element 2");
list.remove(0);
list.removeFirst();
list.removeLast();

4、判断元素是否存在:

  • contains(Object element):检查链表是否包含指定元素。
LinkedList<String> list = new LinkedList<>();
list.add("Element 1");
list.add("Element 2");
boolean containsElement = list.contains("Element 1");

5、获取链表大小和清空链表

  • size():获取链表中元素的个数。
  • isEmpty():检查链表是否为空。
  • clear():清空链表中的所有元素。
LinkedList<String> list = new LinkedList<>();
list.add("Element 1");
list.add("Element 2");
int size = list.size();
boolean isEmpty = list.isEmpty();
list.clear();

链表的优点:可以高效地插入和删除节点,而无需移动其他节点。

缺点:访问特定位置的节点需要从头部开始遍历,随机访问的效率较低。

LinkedList 和 ArrayList 的区别

首先说说动态数组ArrayList:

这是一个集合类型,在其内部维护了一个数组,可以自动调整其大小以容纳更多的元素。当你向这些集合中添加元素时,如果内部数组已满,它们会自动创建一个更大的新数组(扩容),并将旧数组的元素以及新元素复制到新数组中。

内部数组初始容量:10

触发扩容的条件:原有数组elementData满了之后就会扩容

扩容方式:新容量=原容量+(原容量>>1)

数组优点:可以随机访问,效率极高;缺点:需要连续的空间,而链表结构可以比较好的利用碎片化空间

LinkedList 和 ArrayList 的区别:

底层数据结构LinkedList底层基于链表实现,而ArrayList底层基于动态数组实现。

插入和删除操作:由于LinkedList是基于链表数据结构,插入和删除元素的操作比较高效,时间复杂度为O(1),因为只需要调整节点的指针。而ArrayList的底层是动态数组,插入和删除操作需要移动其他元素,时间复杂度为O(n),其中n是元素的数量。

随机访问:ArrayList支持高效的随机访问,可以通过索引快速获取元素,时间复杂度为O(1)。而LinkedList需要从头开始遍历链表才能找到指定位置的元素,时间复杂度为O(n),其中n是索引位置。

内存消耗:由于LinkedList需要额外的指针来维护节点之间的连接关系,因此在存储相同数量的元素时,LinkedList通常会占用更多的内存空间。而ArrayList只需要连续的内存空间来存储元素。

迭代器性能:对于迭代器遍历操作,LinkedList的性能较好,因为只需要遍历链表中的节点即可。而ArrayList在使用迭代器遍历时,由于底层是数组,可能会导致性能稍差。


http://www.niftyadmin.cn/n/5557958.html

相关文章

自己动手写一个滑动验证码组件(后端为Spring Boot项目)

近期参加的项目&#xff0c;主管丢给我一个任务&#xff0c;说要支持滑动验证码。我身为50岁的软件攻城师&#xff0c;当时正背着双手&#xff0c;好像一个受训的保安似的&#xff0c;中规中矩地参加每日站会&#xff0c;心想滑动验证码在今时今日已经是标配了&#xff0c;司空…

漏扫处理:SSH弱算法问题解决

目录 漏洞说明解决方法1. 查看可用的算法2. 禁用弱算法3.检查ssh配置4.重启ssh服务5.ssh测试连接是否正常6.漏扫测试参考链接漏洞说明 通过漏扫得出,服务器SSH支持密钥交换算法,而此算法被认为是弱算法,存在高风险问题。 启用了以下弱算法: diffie-hellman-group-exchage…

高并发解决方案总结

高并发是指在短时间内有大量的用户同时访问系统或服务&#xff0c;导致系统压力剧增&#xff0c;可能出现响应延迟、服务不可用等问题。针对高并发问题&#xff0c;有多种解决方案&#xff0c;以下是一些主要的解决方案&#xff1a; 一、架构层面 负载均衡&#xff1a; 将多…

工控主板:搭载海光3300处理器的全国产化工控主板

最近为客户定做了一款全国产化的工控机主板。搭载海光3300核心板的含有丰富接口的工控主板。

workingset protection/detection on the anonymous LRU list

Working-set protection for anonymous pages [LWN.net] [PATCH v3 0/9] workingset protection/detection on the anonymous LRU list [LWN.net] 14.7 跟踪LRU活动情况和Refault Distance算法-CSDN博客

结合实体类型信息(2)——基于本体的知识图谱补全深度学习方法

1 引言 1.1 问题 目前KGC和KGE提案的两个主要缺点是:(1)它们没有利用本体信息;(二)对训练时未见的事实和新鲜事物不能预测的。 1.2 解决方案 一种新的知识图嵌入初始化方法。 1.3 结合的信息 知识库中的实体向量表示&#xff0b;编码后的本体信息——>增强 KGC 2基…

使用llava模型时调整其输出的最大长度(max-new-tokens)

使用llava模型时调整其输出的最大长度&#xff08;max-tokens&#xff09; 使用cli命令调整max-new-tokens数值 当我们使用llava项目的时候&#xff08;官网github-llava项目网址&#xff09;&#xff0c;我们一般直接运行的里面的CLI Inference这个命令: python -m llava.ser…

嵌入式人工智能应用-第三章 opencv操作2

1 色彩空间与图像表示 1.1 背景介绍 色彩是人的眼睛对于不同频率的光线的不同感受&#xff0c;色彩既是客观存在的&#xff08;不同频率的光&#xff09;又是主观感 知的&#xff0c;有认识差异。所以人类对于色彩的认识经历了极为漫长的过程&#xff0c;直到近代才逐步完善起…