主要内容:1.冒泡、选择、希尔、插入、快速、堆排、归并;2.排序间的比较;3.时间复杂度的优化思想;
一、七种排序
- 冒泡排序BubbleSort:
从头开始遍历,每次向前冒时,都要与下一个数比较,如果当前小就交换两者,这样最大的数就冒到最后了。
- 选择排序SelectSort:
从剩余集合中选择除最大的元素与首位交换,代码min是选择的最小元素。 - 直接插入排序InsertSort:
不断地将第n个元素插入前n-1个有序集合中,最开始前1个元素是有序的,特点是数组本身越有序则时间复杂度越低。 - 希尔排序ShellSort:
希尔排序先分成t组,其中第0、t、2t等等为一组,调整时每次前进t位。这样一遍下来,数据的有序性会得到提高,且它本省的时间复杂度为O(n)。重复m次,程序就变得很有序了,最后让t=1(就是插入排序)整理一般,就得到有序数组了。 - 快速排序
简单来说就是挑一个数,小的放他左边,大的放它右边,深度遍历logn层,每层n次,时间复杂的就是nlogn。 - 堆排序
(1)建立大根堆:从(len-2)/2开始,到根节点,(2)排序:先交换首位再调整堆 - 二路归并排序
从只有1个元素的集合开始,两两归并成有序集合,最后得到的就是有序的序列。
二、排序间的比较
三、时间复杂度的优化
- 希尔对直接插入的优化
根据插入排序的特性,数组本身越有序则时间复杂度越低,而杂乱的数组的排序时间大部分都浪费再插入的向前调整,且越往前时间复杂的越高,由此产生希尔排序。
希尔排序先分成t组,其中第0、t、2t等等为一组,调整时每次前进t位。这样一遍下来,数据的有序性会得到提高,且它本省的时间复杂度为O(n)。重复m次,程序就变得很有序了,最再让t=1(就是插入排序)整理一般,就得到有序数组了。
希尔排序是直接插入排序的优化可以从两个方面理解:1)先整理地较为有序再用直接插入排序,2)本质的提升:往前的次数减少(一个元素往前一位算一次)。 - 堆排的神奇
堆排为什么比普通算法块?就是因为树(堆)这种结构的神奇吗?当然,确实依赖于树的数据结构,但我们要去解开神奇的面纱。
*优化的核心:*要降低时间复杂度,自然是原来的程序有重复或不必要的地方,不然怎么优化?我们优化的手段就是记录(固化)比较结果,省去后续重复比较。
*选择排序复杂在哪里:*在第一遍遍历选择最小的元素,在选择时肯定有这种情况,min=a;a<b;a>c;min=c;,此段代码选出最小的c让其等于min,但a<b这个信息直接就被抛弃了,在第二次选择时还会比较,如此造成资源的浪费,理所当然就会有优化的程序。
*快排的优化:*挑出一个数,比他小的放左边,比它大的放右边,这样左右两边的数就不会再比较了。
*堆排的优化:*建立大根堆,父节点大于孩子结点。
我们来举个例子,建立好大根堆后,元素就比较有规律;之后,交换一次首尾元素并重新调整堆,就使得一个元素有序了。
首先交换首尾,97就到了尾,且是有序的,然后调整堆,结果,89到头,30下来,再次成了大根堆。可以看出让一个元素有序的时间复杂度最最大是O(logn)。