八大排序: 如果按照难易程度来区分:(4个简单排序算法中除了基数排序,剩下3个代码都是双重for循环) 4个简单:直接插入排序,简单选择排序、冒泡排序、基数排序 4个难:希尔排序、堆排序、归并排序、快速排序 如果按照稳定性来区分: 4个稳定:直接插入排序、冒泡排序、归并排序、基数排序 4个不稳定:简单选择排序、快速排序、希尔排序、堆排序
交换变量的方式:但奇数个数据会使中间值变为0!有缺陷
a = a^b; b = a^b; a = a^b; a = a+b; b = a-b; a = a-b;直接插入排序: -->可优化,二分查找下标
每一趟从待排序序列中取出一个值,然后将其插入到己排序好的序列中,默认第一个值是有序的
最极端情况下,如果默认已经有序,直接插入排序的时问复杂度是0(n)
数据越有序,效率越好;数据量不大时,效率也挺高
希尔排序:-->首先有一个缩小增量数组 gap
默认规则: 1.数组中的值进行互素 2.增量从大到小的给值,并且最后一个值一定得是1
让数组整体变得有序 !!!
选择排序:
每一趟从待排序序列中找出最小值所在位置,然后将其和待排序序列第一个值所在位置进行交换
冒泡排序: len个值,需要len-1躺 -->可优化,加标签标记是否有交换
每一趟从左向右,两两比较,如果左边值大于右边值,则交换
(相当于每一趟就可以将待排序序列中的最大值通过两两比较搬运的方式挪动到最后面)
堆排序:基于完全二叉树实现 ,将数组想象成一棵倒置的树,映射关系
时间复杂度:O(n log n)空间复杂度:O(1)
建堆 → 交换堆顶与末尾 → 调整堆 → 循环直到有序
第一次要彻彻底底对每一个非叶子节点排序
大顶堆:父节点 > 子节点,子节点任意
小顶堆:父节点 < 子节点,子节点任意
父推子 --> 2i + 1,2i + 2;子推父 --> (i-1)/2
归并排序:核心合并函数,先分在和,递归实现
使用双指针分别遍历两个数组
每次取较小的元素放入结果数组
一个数组用完后,将另一个数组剩余部分直接追加
比较头部的较小值,依次取出,直到合并完成。
基数排序:不比较数字大小,按位分配。 不能处理负数
从个位到高位,依次将数字放入0-9的桶中再取出,最后自动有序。
执行过程:
找出最大值,确定需要处理的位数
从低位到高位,每一轮都做两件事:
分配:根据当前位(0-9)将数字放入对应的10个桶中//队列实现
收集:按0→9的顺序把桶里的数字依次取出
处理完最高位后,数组自动有序
可以加一个偏移量(负数最小值)来处理负数,和正数一样进行比较,最后减掉偏移量。
快速排序:核心思想: 分治法 + 基准点。
//数据越有序,效率越低 -->要优化,打乱,越乱越好,越有可能均分
1.通过随机函数,随机从待排数据里抽两个值,进行交换;
2.三数取中法:将最左端值,最右端值,最中间值,三数中不大不小的那个值,调整到最左边去;
3.根据待排序序列元素个数N进行判断,如果N过于小,可以调用直接撤入/冒泡。
选择一个基准元素,将比它小的放左边,比它大的放右边,然后递归处理左右两部分。
执行过程:
选基准:通常选第一个或最后一个元素
分区:比基准小的放左边,大的放右边,基准归位
递归:对左右子数组重复上述过程,直到有序
BF算法:枚举法(暴力求解) 判断是否匹配成功只看字串是否遍历走出字串范围
return (i - j);//注意回退要回退到这一趟开始匹配的失败位置的下一个位置 :i-j+1
kmp算法:核心一句话:变量i打死不回退,不要让j无脑回退到0
要寻找最长公共前后缀,next数组(中间部分可以重叠,寻找最长)
触底标记 :-1 默认next数组开始为 : -1,0