时间复杂度
若存在函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于0的常数,则称f(n)是T(n)的同数量级函数。计作T(n)=O(f(n)),称为O(f(n)),O为算法的渐进时间复杂度,简称为时间复杂度。
遵循以下原则:
- 如果运行时间是常数量级,则用常数1表示
- 只保留时间函数中的最高阶项
- 如果最高阶项存在,则省去最高阶项前面的系数
常见时间复杂度:O(1)<O(logn)<O(nlogn)<O(nn)
空间复杂度
S(n)=O(f(n)),n为问题的规模,f(n)为算法所占存储空间的函数
常见空间复杂度情况:
- 常量空间:算法的存储空间大小固定,和输入规模没有直接关系,计作O(1)
- 线性空间:算法分配的空间是一个线性的集合(如数组),并且集合大小和输入规模成正比,计作O(n)
- 二维空间:算法分配的空间是一个二维数组集合,长宽都和输入规模n成正比,空间复杂度计作O(n*n)
- 递归空间:未显式声明,执行程序会分配内存用来存储方法栈调用,包含进栈和出栈,空间复杂度为O(n)
数据结构
线性结构 线性结构是最简单的数据结构,包含数组、链表,以及由他们衍生出的栈、队列、哈希表。
树 树是相对复杂的数据结构,其中比较有代表性的是二叉树,由它又衍生出了二叉堆之类的数据结构。
图 更为复杂的数据结构,图中会呈现出多对多的关联关系。
其他数据结构 除上述基本数据结构外,还有其他的结构。由基本数据结构变形而来,用于解决某些特定问题,如跳表,哈希链表,位图等。
基础数据结构
数组
数组是由有限个相同类型的变量所组成的有序集合,他的物理存储方式是顺序存储,访问方式是随机访问。利用下标查重数组元素的时间复杂度是O(1),中间插入、删除数组元素的时间复杂度是O(n)
链表
链表是一种链式数据结构,由若干节点组成,每个节点包含指向下一个节点的指针。链表的物理存储方式是随机存储,访问方式是顺序访问。查找链表节点的时间复杂度是O(n),中间插入,删除节点的时间复杂度是O(1)
栈
栈是一种线性逻辑结构,可以用数组实现,也可以用链表实现。包含入栈和出栈操作,遵循先入后出的原则。
队列
队列是一种线性逻辑结构,可以用数组实现,也可以用链表实现。包含入队和出队操作,遵循先入先出原则。
散列表
散列表也叫做哈希表,是存储KEY-Value映射的集合。对于某一个key,散列表可以在接近O(1)的时间内读写操作。散列表通过哈希函数实现KEY和数组下标的转换,通过开放寻址法和链表法来解决哈希冲突。