排序
类别 | 排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | ||
最好 | 平均 | 最差 | ||||
基于比较的排序 | 插入排序 | O(N) | O(N^2) | O(N^2) | O(1) | 稳定 |
选择排序 | O(N^2) | O(N^2) | O(N^2) | O(1) | 不稳定 | |
堆排序 | O(NlogN) | O(NlogN) | O(NlogN) | O(1) | 不稳定 | |
冒泡排序 | O(N) | O(N^2) | O(N^2) | O(1) | 稳定 | |
快速排序 | O(NlogN) | O(NlogN) | O(N^2) | O(logN) | 不稳定 | |
归并排序 | O(NlogN) | O(NlogN) | O(NlogN) | O(N) | 稳定 | |
不基于比较的排序 | 计数排序 | O(N) | O(N) | O(N) | 与词频表有关 | |
基数排序 | 稳定 | |||||
排序算法稳定性:同样值的个体之间,如果不因为排序而改变相对次序,就是稳定的
稳定性的现实意义:商品先根据价格升序排序,再根据质量降序,返回的前几个一定是物美价廉的
工程上对排序的改进:充分利用O(NlogN)和O(N^2)的优势,例如对快排来说,大样本量使用快排,小样本量的时候插入排序
系统实现的sort ,底层实现:如果是基本数据类型,就用快排,如果非基本数据类型就用归并。原因:基本数据类型的话,没用稳定性的需求,所以用快排;反之,非基本数据类型,为了支持稳定性,使用归并
解决哈希冲突的四种方法
1.开放地址方法
(1)线性探测
按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上往后加一个单位,直至不发生哈希冲突。
(2)再平方探测
按顺序决定值时,如果某数据的值已经存在,则在原来值的基础上先加1的平方个单位,若仍然存在则减1的平方个单位。随之是2的平方,3的平方等等。直至不发生哈希冲突。
(3)伪随机探测
按顺序决定值时,如果某数据已经存在,通过随机函数随机生成一个数,在原来值的基础上加上随机数,直至不发生哈希冲突。
2.链式地址法(HashMap的哈希冲突解决方法)
对于相同的值,使用链表进行连接。使用数组存储每一个链表。
优点:
(1)拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
(2)由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
(3)开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间;
(4)在用拉链法构造的散列表中,删除结点的操作易于实现。只要简单地删去链表上相应的结点即可。
缺点:
指针占用较大空间时,会造成空间浪费,若空间用于增大散列表规模进而提高开放地址法的效率。
3.建立公共溢出区
这种方法的基本思想是:将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表
4.再哈希法
这种方法是同时构造多个不同的哈希函数:
Hi=RH1(key) i=1,2,…,k
当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。