1. 常用线性数据结构
数组: 底层连续内存存储。特点是:提供随机访问并且容量有限。
链表:
栈:
队列:
*优先队列 (Priority Queue) 从底层结构上来讲并非线性的数据结构,它一般是由堆来实现的。
2. 常用非线性数据结构
图:
堆:
堆是一种满足以下条件的树:堆中的每一个节点值都大于等于(或小于等于)子树中所有节点的值。或者说,任意一个节点的值都大于等于(或小于等于)所有子节点的值。
树:
二叉树的分类:满二叉树、完全二叉树、平衡二叉树(平衡二叉树的常用实现方法有 红黑树、AVL 树、替罪羊树、加权平衡树、伸展树 等)
3. KMP算法
step 1:寻找模式串(子串)前缀后缀最长公共元素长度。
step 2:计算next数组。将1中求得的值整体减一。且初值赋为-1
step 3:根据next数组进行匹配。
当j=-1或者当前字符匹配成功,i++,j++
当j != -1,且当前字符匹配失败。j=next[j]
时间复杂度:o(n+m)
4. 最长公共前缀
只需要对字符串数组arrays.sort()以后,比较第一个字符串与最后一个字符串即可。
5. 排序
排序算法: 内部排序(数据记录在内存中)和外部排序
常见的内部排序算法
最好 | 最坏 | 平均 | 空间 | 稳定性 | |
冒泡排序 | O(n) | O() | O() | O(1) | 稳定 |
选择排序 | O() | O() | O() | O(1) | 不稳定 |
插入排序 | O(n) | O() | O() | O(1) | 稳定 |
希尔排序 | O(n log n) | O() | O(n log n) | O(1) | 不稳定 |
快速排序 | O(n log n) | O(n log n) | O(n log n) | O(log n) | 不稳定 |
归并排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | 稳定 |
堆排序 | O(n log n) | O(n log n) | O(n log n) | O(1) | 不稳定 |
(1) 冒泡排序。
可以加一个flag,目的是将算法的最佳时间复杂度优化为 O(n)
,即当原输入序列就是排序好的情况下,该算法的时间复杂度就是 O(n)
。
(2)选择排序。
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
(3)插入排序
像打扑克牌。
(4)希尔排序
基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 “基本有序” 时,再对全体记录进行依次直接插入排序。
(5)快速排序
快速排序的基本思想:通过一趟排序将待排序列分隔成独立的两部分,其中一部分记录的元素均比另一部分的元素小,则可分别对这两部分子序列继续进行排序,以达到整个序列有序
以最后一个为基准, pointer初始为数组开头,从数组start位置开始,到end-1位置结束,寻找小于基准的数,将其与pointer交换,然后pointer++。最后将pointer位置与基准交换。 然后排序(start,pointer-1)和(pointer+1,end)。
(6)归并排序
二路归并为例:若将两个有序表合并成一个有序表,称为 2 - 路归并。
(7)堆排序
① 优先队列可以实现
② 数组