BV15b4y117RJ
目录目标:手写代码、掌握细节
细节:
1. 避免整数溢出:L+R可能超出Integer.MAX_VALUE。
方法一:改成 L/2+R/2 → L + (R-L)/2
方法二:改成位计算(无符号右移) (L+R) >>> 1
2. 变体 (详见leetcode)
目标:掌握思路,手写代码,了解特性(时间复杂度、是否稳定)
(升序)每轮 依次比较相邻两个元素的大小,若a[j]>a[j+1]则交换位置,使得最大的元素排到最后
优化:
1. 减少比较次数(每轮冒泡的比较次数递减)
2. 减少冒泡次数(发现本轮没有进行交换,说明数组整个都有序了不用再排序了),
3. 进一步优化:记录每轮的最后一次进行交换的索引,来得到下轮的比较次数。若为0这说明全排完了(相当于优化2)
(升序)每轮选择出数组后部分中最小的元素,移到数组前部分
i代表每轮选择最小元素要交换到的目标索引
稳定:相同元素不会打乱位置
数组开头保持为有序的。把后面的元素一个一个插入到开头的有序组中。
性质:稳定的
缺点:很大的元素位于前面的话,要移动很多次位置才能到达目标位置希尔排序
改进了插入排序。把整个数组按一定间隔分组,分别进行插入排序插入和选择—推导第n轮后的结果
1.每一轮排序选择一个基准点(pivot)进行分区
1.让小于基准点的元素的进入一个分区,大于基准点的元素的进入另一个分区2.当分区完成时,基准点元素的位置就是其最终位置
2.在子分区内重复以上过程,直至子分区元素个数少于等于1,这体现的是分而治之的思想(divide-and-conquer)
单边循环快排(Lomuto):
双边循环快排:
快排的特点数据量特别大的时候用快排,其中分区长度比较小的时候用插排
初始化:
添加元素超出容量时会扩容。
fail-fast
一旦发现遍历时其他人来修改,则抛异常
ArrayList用modCount记录修改次数,遍历中检查发现modCount与预期不符则说明被修改过了,终止遍历
fail-safe(CopyOnWriteArrayList)
允许修改,牺牲一致性(以老数据为准)让遍历完成
------------恢复内容结束------------