zoukankan      html  css  js  c++  java
  • 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最初建议步长选择为frac{n}{2}并且对步长取半直到步长达到1。优化的选择Sedgewick提出的(1, 5, 19, 41, 109,...),该序列的项来自9	imes 4^{i}-9	imes 2^{i}+12^{{i+2}}	imes (2^{{i+2}}-3)+1,希尔排序最重要的是比较而不是交换。

    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、

  • 相关阅读:
    RecyclerView,ListView first item get focus
    一种粗暴快速的Android全屏幕适配方案(转)
    谈谈单元测试之(一):为什么要进行烦人的单元测试(转)
    SCIgen与野鸡期刊的梗
    百度搜索仍然是【最快解决工作问题的方法】
    搭建minima主题的github博客网站
    本科期间的第一个专利:改卷筒的故事
    学习消费思维的【贫穷与富有】
    我的联系方式
    学习 GitHub 有什么好处?
  • 原文地址:https://www.cnblogs.com/lingli-meng/p/7477397.html
Copyright © 2011-2022 走看看