目录
顺序表和链表
1. 线性表
线性表
(
linear list
)
是
n
个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常
见的线性表:顺序表、链表、栈、队列、字符串
...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存
储时,通常以数组和链式结构的形式存储。

2. 顺序表
2.1 概念及结构
顺序表是用一段
物理地址连续
的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成
数据的增删查改。
顺序表一般可以分为:
静态顺序表:使用定长数组存储。
动态顺序表:使用动态开辟的数组存储。
静态顺序表适用于确定知道需要存多少数据的场景
.
静态顺序表的定长数组导致
N
定大了,空间开多了浪费,开少了不够用
.
相比之下动态顺序表更灵活
,
根据需要动态的分配空间大小
.
2.2 接口实现
我们来实现一个动态顺序表
.
以下是需要支持的接口
.
public class SeqList {
// 打印顺序表
public void display() { }
// 在 pos 位置新增元素
public void add(int pos, int data) { }
// 判定是否包含某个元素
public boolean contains(int toFind) { return true; }
// 查找某个元素对应的位置
public int search(int toFind) { return -1; }
// 获取 pos 位置的元素
public int getPos(int pos) { return -1; }
// 给 pos 位置的元素设为 value
public void setPos(int pos, int value) { }
//删除第一次出现的关键字key
public void remove(int toRemove) { }
// 获取顺序表长度
public int size() { return 0; }
// 清空顺序表
public void clear() { }
2.3 顺序表的问题及思考
1.
顺序表中间
/
头部的插入删除,时间复杂度为
O(N)
2.
增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
3.
增容一般是呈
2
倍的增长,势必会有一定的空间浪费。例如当前容量为
100
,满了以后增容到
200
,我们再继 续插入了5
个数据,后面没有数据插入了,那么就浪费了
95
个数据空间。
思考
: 如何解决以上问题呢?下面给出了链表的结构来看看
3. 链表
3.1 链表的概念及结构
链表是一种
物理存储结构上非连续
存储结构,数据元素的
逻辑顺序
是通过链表中的
引用链接
次序实现的
实际中链表的结构非常多样,以下情况组合起来就有8
种链表结构:
单向、双向
带头、不带头

循环、非循环
虽然有这么多的链表的结构,但是我们重点掌握两种
:
无头单向非循环链表:
结构简单
,一般不会单独用来存数据。实际中更多是作为
其他数据结构的子结构
,如
哈希桶、图的邻接表等等。另外这种结构在
笔试面试
中出现很多。
无头双向链表:在
Java
的集合框架库中
LinkedList
底层实现就是无头双向循环链表。
3.2 链表的实现
3.3 链表面试题
1.
删除链表中等于给定值
val
的所有节点。
// 1、无头单向非循环链表实现
public class SingleLinkedList {
//头插法
public void addFirst(int data);
//尾插法
public void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
public boolean addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key);
//删除第一次出现关键字为key的节点
public void remove(int key);
//删除所有值为key的节点
public void removeAllKey(int key);
//得到单链表的长度
public int size();
public void display();
public void clear();
}
2.
反转一个单链表。
// 2、无头双向链表实现
public class DoubleLinkedList {
//头插法
public void addFirst(int data);
//尾插法
public void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
public boolean addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key);
//删除第一次出现关键字为key的节点
public void remove(int key);
//删除所有值为key的节点
public void removeAllKey(int key);
//得到单链表的长度
public int size();
public void display();
public void clear();
4. 顺序表和链表的区别和联系
顺序表:
白:空间连续、支持随机访问
丑:
1.
中间或前面部分的插入删除时间复杂度
O(N) 2.
增容的代价比较大。
链表:
胖黑:以节点为单位存储,不支持随机访问
所有:
1.
任意位置插入删除时间复杂度为
O(1) 2.
没有增容问题,插入一个开辟一个空间。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现