数据结构与算法(Java语言描述)
数据结构基础知识(Data structures)
数组(Array)
特点
- 用连续的内存空间存储相同类型的数据
- 数组有长度,且一旦创建无法更改,不支持扩容
- 通过下标/索引操作数组中的数据
链表(LinkedList)
应用场景
内存分散,且需要存储的内容需要连续查找并且大于散布的内存
特点
- 占用非连续的内存空间
- 节点之间通过指针连接
- 天然支持扩容
链表操作
链表应用场景举例
双指针-快慢指针
- 检测链表中的环
- 找到链表的中间节点
- 找到链表的倒数第K个节点
- ……
注意:
- 两个指针同向而行,按不同的速度或策略移动
- 常用于检测是否成环,查找链表某些特定节点等
- 明确指针的初始位置,移动速度/策略,停止条件,仔细处理边界情况
双指针-左右指针
注意
- 两个指针从两端相向而行,相遇时结束
- 相遇时,可能已经遍历了某个特定部分或满足了某个条件
- 根据题设条件确定哪个指针走
数组和链表的对比
小结
数组的特点:
-
连续的内存空间存储相同类型的数据
-
长度固定后不支持扩容
-
通过下标操作数据
链表的特点:
- 非连续的内存空间
- 节点之间通过指针连接
链表的操作:
- 新增/删除:修改next指针
- 遍历:根据next指针查找
时间复杂度
定义:
反映了算法执行时间(次数)随着处理的数据规模的增长而变化的趋势
注意:
- 只需关注最大的数量级
- 常见时间复杂度:O(1),O(n),O(log n),O(n*log n),O(n^2)
- 最好、最坏、平均时间复杂度
分析原则:
最大循环原则,加法原则,乘法原则
数组操作时间复杂度
链表操作时间复杂度
空间复杂度
定义:
算法占用的额外存储空间与数据规模之间的增长关系
常见的空间复杂度:
O(1),O(n)
栈
特点
- 只允许在栈的一端进行数据的入栈和出栈操作
- 元素后进先出(LIFO)
- 入栈,出栈时间复杂度均为O(1)
- 栈可以用数组实现也可以用链表实现
队列
特点
- 元素从一端入队列,从另一端出队列
- 元素先进先出(FIFO)
- 入队列,出队列的时间复杂度均为O(1)
- 队列可以用数组实现也可以用链表实现