基础线性结构
线性结构是一个有序数据元素的集合。线性结构--数组、栈、队列、链表介绍
前言
线性结构是一个有序数据元素的集合。线性结构--数组、栈、队列、链表介绍
正文
Array 数组
Array 是一种线性结构,把数据码成一排进行存放,只能存放
同一种类型
多个元素。
- Java Array 属于
静态数组
- Array 最大的优点:
快速查询
。例如:arr[1] - Array 最好应用与
索引有语意
的场景。 - 但并非所有有语意的索引都适应于 Array。有些索引如(身份证号)长度太长了导致空间被浪费。
相关操作 添加操作 删除操作 修改操作 查找操作 复杂度 O(n) O(n) 已知索引 O(1);未知索引 O(n) 已知索引 O(1);未知索引 O(n)
Stack 栈
Satck 是一种
先进后出
的线性结构。
- 相比数组,栈对应的操作是数组的子集,只能从一端添加元素,也只能从这一端取出元素。这一端称为
栈顶
。 - 栈只能在
栈顶
操作数据: 在表尾
进行插入和删除操作。 - 栈的使用场景: 我们经常使用的
Undo
(撤销操作)、程序调用的系统栈、括号匹配。 相关操作 入栈 出栈 查看栈顶 查看元素数量 判断是否为空 复杂度 O(1)均摊 O(1)均摊 O(1) O(1) O(1)
Queue 队列
Queue 是一种
先进先出
的线性结构。
相比数组,队列对应的操作是数组的子集。只能从一端
队尾
添加元素,只能从另一端队首
取出元素。队列的分类:
数组队列
、循环队列
循环队列
必定是要浪费掉一个空间
不能存储数据的循环队列 队列为空 队列满 (c 表示队列的容量) 条件 front == tail (tail + 1) % c == front 相关操作 入队 出队 查看队首 查看元素数量 判断是否为空 复杂度 O(1)均摊 O(n) O(1) O(1) O(1)
注意
数组队列出列
的时间复杂度为O(n)
,而循环队列均摊下来的复杂度为O(1)
.
LinkedList 链表
最简单
、真正
的动态数据结构,数据存储在节点Node
中。
节点
: 把数据存储在一种单独数据结构中,一部分是数据,一部分是下一个节点,最后
一个节点是NULL
。- 链表在添加和删除中,对数据操作的
顺序很重要
。在中间添加时,先将该元素的前一个节点找出来。 - 优点:
真正的动态数据
,不需要像 Array、Stack、Queue 处理固定容量的问题 - 缺点: 不适合用于索引
有语意
的情况,因为它丧失
了随机
访问数据的能力
Recursion 递归
递归
: 本质上,将原来的问题,转化为更小的同一问题
- 递归
基本原则
: 所有递归问题基本上都可以分为以下两部分
- 求解
最基本
问题(这个最基本问题是不能自动求解的,需要编写逻辑求解的) - 把原问题转化成
更小
的问题(核心部分)
- 举例 : 数组求和
Sum(arr[0...n-1]) = arr[0] + Sum(arr[1...n-1]) <- 更小的同一问题(少了一个元素)
Sum(arr[1...n-1]) = arr[1] + Sum(arr[2...n-1]) <- 更小的同一问题(少了一个元素)
. . . . . .
Sum(arr[n-1...n-1]) = arr[n-1] + Sum([]) <- 最基本的问题
- 代码
public static int sum(int[] arr){
return sum(arr, 0);
}
// 计算arr[l...n)这个区间内所有数字的和
private static int sum(int[] arr, int l){
if(l == arr.length)
return 0; <- 最基本的问题
return arr[l] + sum(arr, l + 1); <- 更小的同一问题
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5, 6, 7, 8};
System.out.println(sum(nums));
}