① 从第一个元素开始,该元素可以认为已经被排序 ② 取出下一个元素,在已经排序的元素序列中从后向前扫描 ③如果该元素(已排序)大于新元素,将该元素移到下一位置 ④ 重复步骤③,直到找到已排序的元素小于或者等于新元素的位置 ⑤将新元素插入到该位置后 ⑥ 重复步骤②~⑤
具体代码实现:
①平均时间复杂度:O(N^2) ②最差时间复杂度:O(N^2) ③空间复杂度:O(1) ④稳定性:稳定
希尔排序(ShellSort)是对插入排序最坏的情况的改进,主要是减少数据移动次数,增加算法的效率。
将要排序的序列按照步长gap进行分组,先在这几组内进行插入排序,之后再进行整体的插入排序,gap步长的选择是希尔排序最重要的部分,要保证最后一次排序的步长为1,这样就会保证整个数组将会被排序,并且步长必须小于数组长度。
①最好情况:时间复杂度为O(n) ②最坏情况下:时间复杂度为O(n^2) ③空间复杂度为:O(1) ④稳定性:不稳定
选择排序原理即是,遍历元素找到一个最小(或最大)的元素,把它放在第一个位置,然后再在剩余元素中找到最小(或最大)的元素,把它放在第二个位置,依次下去,完成排序。
(1)时间复杂度:O(n^2; (2)空间复杂度:O(1; (3)稳定性:不稳定;
堆是一个按照完全二叉树存储的数组,它是一个近似的完全二叉树但是同时它又满足堆的性质。
.从小到大排序建大堆,从大到小排序建小堆 把堆顶的元素和当前堆的最后一个元素交换 堆的元素个数减一 从根节点向下调整
.从小到大排序建大堆,从大到小排序建小堆
把堆顶的元素和当前堆的最后一个元素交换
堆的元素个数减一
从根节点向下调整
(1)最好情况下时间复杂度为:O(nlogn) (2)最坏情况下时间复杂度为:O(nlogn) (3)空间复杂度为:O(1) (4)稳定性:不稳定
冒泡排序和选择排序差不多,都是与后面挨个比较,将最小的放到前面。
冒泡排序是一种简单的排序算法,它不断地重复遍历数组,每次与其相邻的数进行比较,如果他们的顺序错误就交换,直到数组只剩下一个元素的时候,说明该数组已经排好序,之所以成为冒泡排序,是因为越小的元素会经由交换慢慢“浮”到数列的前面。
(1)最坏情况时间复杂度为:O(n^2)。 (2)平均情况时间复杂度为:O(n^2)。 (3)需要额外空间:O(1)。 (4)稳定性:稳定。
快速排序是目前应用最广,最有意思的一个排序算法,速度快,空间利用率高,名副其实是理想中最快的算法了。
这里是引用选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
①设置基准值,也就是数组的第一个元素。 ②先将temp所在的位置设置为坑,然后从left开始找比temp大的数,找到后填上刚才temp处所设的坑,并且将找到的最大数的位置设为坑。 ③end开始找比key小的数放到刚才最大数位置所设的坑处。 ④这样就将数组分为两个子区间,如此循环。
①将左边设为temp; ②先从右边开始找比temp小的,再从左边开始找比temp大的,然后将两个交换。重复此步骤; ③left和right相遇,将left和temp交换;
①定义两个指针前后开始遍历; ②当后面的指针的值小于temp,并且它不等于前一个指针的下一个,交换两个值; ③当一个指针到达最右边,最后交换前一个指针和temp的值;
(1)时间复杂度:最好情况:O(n*logn); 最坏情况: O(n^2); (2)空间复杂度:最好情况:O(logn); 最坏情况:O(n); (3)稳定性:不稳定;
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
(1)分解(Divide):将n个元素分成个含n/2个元素的子序列。 (2)解决(Conquer):用合并排序法对两个子序列递归的排序。 (3)合并(Combine):合并两个已排序的子序列已得到排序结果。
(1)时间复杂度:O(n*logn); (2)空间复杂度:O(n); (3)稳定性:稳定;
数据量规模较小,考虑插入或选择。当元素分布有序时插入将大大减少比较和移动记录的次数,如果不要求稳定性,可以使用选择,效率略高于插入; 数据量规模中等,使用希尔排序; 数据量规模较大,考虑堆排序(元素分布接近正序或逆序)、快速排序(元素分布随机)和归并排序(稳定性); 一般来说不使用冒泡。