一、两种复杂度
1.时间复杂度
常用数据结构复杂度
多个复杂度同时存在时,只看最高的复杂度
时间复杂度曲线:
感慨: 到 2^n以及n!简直逆天
常用时间复杂度
二分查找:o(logn)
二叉树遍历-前序、中序、后序:o(n)
二叉搜索树遍历-前序、中序、后序:o(logn)
图的时间复杂度:o(n)
DFS、BFS搜索算法:o(n)
2.空间复杂度
如果是数组,一维数组的长度就是空间复杂度o(n)。二维数组的空间复杂度o(n^2)。
如果是递归,递归的最大深度就是空间复杂度。
如果是递归里面开了数组,那就取两者最大值。
二、两种底层实现
1.数组
数组末尾添加
指定位置添加
2.链表
时间复杂度:
插入、添加、删除:o(n)
查询:o(1)
链表添加节点
链表删除节点
双链表
三、基础数据结构
1.栈
特点:后进先出,添加、删除皆为 O(1)
Java中利用集合操作栈,可以采用LinkedList和Stack
LinkedList是双端队列,采用双链表实现。它同时支持push和pop操作。
2.队列
特点:先进先出,添加、删除皆为 O(1)
Queue源码
区别:
add,remove,element这组抛出异常
offer,poll,peek这组返回值
public interface Queue<E> extends Collection<E> {
boolean add(E e);//添加
boolean offer(E e);//添加
E remove();//移除
E poll();///移除
E element();//查看
E peek();//查看
}
3.双端队列
两端都可以进出的队列,特点:插入和删除都是 O(1) 操作
java集合里面是LinkedList实现
4.跳表
跳表特点:
- 只能用于元素有序 跳表对标的是平衡树和二分查找
- 跳表的插入、删除、搜索的时间复杂度为o(logn)
- 跳表空间复杂度o(n)
- 优势是原理简单、容易实现、方便扩展、效率更高。
- 在热门的项目里面用来替代平衡树,如Redis、LevelDB等。
跳表时间复杂度
假如要寻找8
寻找路径:4->6->7
寻找次数3
㏒2 8=3
时间复杂度为㏒2,即为o(longn)
5.哈希表
哈希表(Hashtable),也叫散列表,是根据关键码值(Keyvalue)而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫作散列函数(HashFunction),存放记录的数组叫作哈希表(或散列表)。
常用于缓存、键值对存储
- 在java中的集合中为map和set
- Map:key-value对,key不重复
- Set:不重复元素的集合
HashSet底层用的HashMap
HashSet的add操作底层就是HashMap的put操作
HashMap底层实现和原理
Java集合容器面试题
TreeMap和TreeSet都是采用红黑树实现
时间复杂度
如果哈希表的size太小或者经常发生哈希碰撞,哈希表就会退化成链表,时间复杂度就变为o(n)了。
6.树
为啥会有树?
单链表的查询时间复杂度为o(n).如果想要加速,那么得进行升维,从一维升维二维。可以变为跳表,时间复杂度为o(logn)。也可以变为树。树就是单链表有多个子节点。
树的遍历
前序:根左右
中序:左根右
后序:左右根
树的遍历代码实现:递归和迭代
二叉搜索树
查询和插入都是o(logn)
二叉搜索树的遍历
类似二分查找,每次遍历都会筛掉一半的节点,所以时间复杂度
为o(logn)
最坏情况,二叉搜索树都是单分支,退化成链表,时间复杂度就变为o(n)了。
7.图
区别树和图就是看是否有环
图是由结点的有穷集合V和边的集合E组成。其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系。
无向无权图
有向无权图