1. List简介
List是Java中的一种数据结构。
Collection
的接口如下图所示。其中List的接口有ArrayList
和LinkedList
,分别表示顺序表和链表。
2. LinkedList
链表(
Linkedlist
)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
链表可分为单向链表和双向链表。
基础操作
1.创建链表
// 引入 LinkedList 类
import java.util.LinkedList;
LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
// 或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表
2.添加元素
// 在列表开头添加元素
list.add();
// 在列表尾添加元素
list.addLast()
3.删除元素
// 移除头部元素
list.removeFirst()
// 移除尾部元素
list.removeLast()
4.获取元素
// 获取头部元素
list.getFirst()
// 获取尾部元素
list.getLast()
5.获取链表元素数量
//获取链表元素数量
list.size()
3. ArrayList
ArrayList
是一个可以动态修改的数组,它的大小不是固定的,我们可以添加或删除元素。ArrayList
继承了AbstractList
,并实现了 List 接口。
基础操作
1.创建顺序表
import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>(); // 初始化
2.增
list.add();
3.删
// 删除第一个元素
list.remove(0);
4.改
// 修改第二个元素
list.set(1,'改成这个字符串');
5.查
// 返回第三个元素
list.get(2);
6.获取ArrayList中的元素数量
// 返回元素数量
list.size();
7.获取ArrayList中的元素数量
// 排序
Collections.sort(list);
其他操作
将链表转为一维数组 toArray(T[] a)
list.toArray(new String[0])
将链表转为二维数组 toArray(T[] a)
list.toArray(new int[0][]);
4. Arrays
给一维数组排序
Arrays.sort()
给二维数组排序
Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);
链表反转 - 迭代 与 递归
链表是一种十分常见的数据结构,它是线性表但是不会按照线性的顺序去存存储数据,链表中的每一个结点都含有一个
’next’
,这个’next’
就是存储的下一个结点的信息。
同时链表反转是一道非常热门的算法基础题,让我们来一起看一看这道题吧
1.链表反转题目:
分析
解法一:使用头插法返回一个新的结果链表,因为头插法产生的链表就是逆序的。因此刚好就是反转过来的链表。
解法二:使用双指针,直接将链表中的指针全部改变方向,最终产生的链表就是反转过来的链表。
2.链表的反转
链表反转是一种十分常见的操作 ,通常情况下我们会使用递归的方法来对链表的反转进行实现。
public void reverse() {// 反转整个链表}
private Node reverse(Node curr) {// 反转单个结点,并返回这个结点的值}
在链表类中定义两个方法,第一个是用来反转整个链表,这个方法的实现需要调用第二个方法。 第二个方法是第一个方法的重载,也是反转链表的核心方法。
反转链表的本质是讲头结点也及时head
结点指向原链表的最后一个结点,然后再相当于倒序的将这个元素的’next’指向原链表中指向它的元素(这里比较绕,需要多想想),我们对每个元素都这么做,链表的反转也就实现了。
public void reverse() {
// 首先判断链表是否为空
if (isEmpty()) {
return;
}
// 递归将第一个结点传入就相当于反转了整个链表
reverse(head.next);
}
private Node reverse(Node curr) {
// 递归算法
if (curr.next == null) {
head.next = curr;
return curr;
}
Node next_node = reverse(curr.next);
next_node.next = curr;
curr.next = null;
return curr;
}
假如此时我们有链表“1 -> 2 -> 3 -> 4”,我们想要反转整个链表,传入的参数就是第一个结点1,reverse就会不断执行代码块中1,2的步骤直到curr =4,这是链表中的最后一个结点,此时我们让头结点’head’的’next’指向4,然后执行 return curr; 这个时候curr = 4
4会当成参数进行递归,我们看方法里的参数即 curr.next = 4,这句话对应的是原链表中3的’next’ 等于4,next_node
这个时候是等于4的,这个时候让4的’next’等于3,即此时反转的链表是head -> 4 -> 3同理3也会返回进方法里递归,当全部递归完成之后,链表也就反转成功了。
4.测试
/*
* @author: Gou JiaTao
* @date: 2021/7/19 14:59
* @SoftWare: IDEA
*/
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.insert("李明");
list.insert("小红");
list.insert("peter");
list.insert("tom");
list.insert("张三");
System.out.println("反转之前的链表:");
for (String s : list) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("反转之后的链表:");
list.reverse();
for (String s : list) {
System.out.print(s + " ");
}
运行结果:
关联算法文章:
这里有一些相关的文章,可以参考一下
1、斐波那契数列的迭代算法和递归算法
2、埃氏筛法(埃氏算法)
3、BF算法(暴⼒算法)-- 模式匹配算法
4、数据结构:八大数据结构分类
5、JAVA中 常用七大排序算法
6、Linked 链表反转 - 迭代 与 递归