3、希尔排序(递减增量排序算法)不稳定的-- - - 直接插入排序的改进 、复杂度介于O(nlog^2n)~ O(n),空间是O(n)
基于插入排序的两点性质:
1、对于几乎已排好序的数组效率高,可达到线性
2、但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位
方法:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,可以让一个元素可以一次性地朝最终位置前进一大步。然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的。
理解为:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更小了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。
例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ]
,如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:按列排序
13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10
步长选择:Donald Shell最初建议步长选择为并且对步长取半直到步长达到1。优化的选择Sedgewick提出的(1, 5, 19, 41, 109,...),该序列的项来自和,希尔排序最重要的是比较而不是交换。
coding:
//对直接插入排序的改写
public static void shellSort(int[] data) { int j = 0; int temp = 0; //每次将步长缩短为原来的一半 for (int increment = data.length / 2; increment > 0; increment /= 2) { for (int i = increment; i < data.length; i++) { temp = data[i]; for (j = i; j >= increment; j -= increment) { if(temp > data[j - increment])//如想从小到大排只需修改这里 { data[j] = data[j - increment]; } else { break; } } data[j] = temp; } } } 4、效率: 作者:shadow000902 链接:http://www.jianshu.com/p/8c915179fd02 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
4、 选择排序(Selection sort),它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。
选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。
/** * 选择排序算法 * 在未排序序列中找到最小元素,存放到排序序列的起始位置 * 再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。 * 以此类推,直到所有元素均排序完毕。 * @param numbers */ public static void selectSort(int[] numbers) { int size = numbers.length; //数组长度 int temp = 0 ; //中间变量 for(int i = 0 ; i < size ; i++) { int k = i; //待确定的位置 //选择出应该在第i个位置的数 for(int j = size -1 ; j > i ; j--) { if(numbers[j] < numbers[k]) { k = j; } } //交换两个数 temp = numbers[i]; numbers[i] = numbers[k]; numbers[k] = temp; } } 作者:shadow000902 链接:http://www.jianshu.com/p/8c915179fd02 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
5、