8大排序算法-我熟知二(希尔选择)

Posted Scarlett meng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8大排序算法-我熟知二(希尔选择)相关的知识,希望对你有一定的参考价值。

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、

 


以上是关于8大排序算法-我熟知二(希尔选择)的主要内容,如果未能解决你的问题,请参考以下文章

图解程序员必须掌握的Java常用8大排序算法

8大排序算法---我熟知3(归并排序/快速排序/堆排序)

Java常用排序算法/程序员必须掌握的8大排序算法

Java常用排序算法/程序员必须掌握的8大排序算法

排序进阶——希尔排序(算法二)

Java学习笔记之十一Java中常用的8大排序算法详解总结