总结:
1、 时间复杂度记忆-
冒泡、选择、直接 排序需要两个for循环,每次只关注一个元素,平均时间复杂度为O(n2)O(n2)(一遍找元素O(n)O(n),一遍找位置O(n)O(n))
快速、归并、希尔、堆基于二分思想,log以2为底,平均时间复杂度为O(nlogn)O(nlogn)(一遍找元素O(n)O(n),一遍找位置O(logn)O(logn))
2、 稳定性记忆-“快希选堆”(快牺牲稳定性)
排序算法的稳定性:排序前后相同元素的相对位置不变,则称排序算法是稳定的;否则排序算法是不稳定的。
一、选择排序
思想:
每次从待排序的数据元素中选出最小的一个元素存放在序列的起始位置
即:在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;
第二次遍历n-2个数,找到最小的数值与第二个元素交换;
。。。
第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。
具体过程:
Java代码:
二、堆排序
思想:
主要解决两个问题:1)如何将一个无序序列变成一个堆? 2)如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?
建堆得过程:将堆看成一个完全二叉树,则二叉树中所有非终端节点得值均不大于左右孩子节点得值。堆顶元素必定是最大值或者是最小值
输出堆顶元素得过程:将堆顶和最后一个元素交换,然后重新建成一个小顶堆或者大顶堆
具体过程:
Java代码:
三:插入排序
思想:在含有i-1个记录得有序子序列r[1..i-1]中插入r[i]后,变成含有i个记录得有序子序列。为了避免数组下标越界,在r[0]处设置监视哨
具体过程:
Java代码:
四:希尔排序
思想:
在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。
然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。
具体过程:(增量分别是4,2,1)
Java代码:
五:交换排序--冒泡排序
思想:
两个数比较大小,较大的数下沉,较小的数冒起来。
比较相邻的两个数据,如果第二个数小,就交换位置。
从后向前两两比较,一直到比较最前两个数据。最终最小数被交换到起始的位置,这样第一个最小数的位置就排好了。
继续重复上述过程,依次将第2.3...n-1个最小数排好位置。
具体过程:
Java代码:
六:交换排序--快速排序
思想:
1、先从数列中取出一个数作为key值;
2、将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边;
3、对左右两个小数列重复第二步,直至各区间只有1个数。
具体过程:
Java代码:
七:归并排序
思想:
定义:是将两个或多个有序表合成一个新的有序表
假设初始序列含有n个记录,看成是n个有序的子序列,每个子序列的长度为1.
之后两两归并,得到【n/2】个长度为2或者1的有序序列。
再两两归并。。。。重复该过程,直到得到一个长度为n的有序序列
具体过程:
可以将A,B组各自再分成2组。
依次类推,当分出来的小组只有1个数据时,可以认为这个小组组内已经达到了有序,
然后再合并相邻的2个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序
Java代码: