你的位置:首页 > Java教程

[Java教程]必须知道的八大种排序算法【java实现】(二) 选择排序,插入排序,希尔算法【详解】


一、选择排序

  1、基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
  
  2、实例

 

  3、算法实现

   /**   * 选择排序算法   * 在未排序序列中找到最小元素,存放到排序序列的起始位置    * 再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。   * 以此类推,直到所有元素均排序完毕。   * @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;  }  }

 

 

二、插入排序

  1、基本思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。

  2、实例

  

  3、算法实现

   /**    * 插入排序   *   * 从第一个元素开始,该元素可以认为已经被排序   * 取出下一个元素,在已经排序的元素序列中从后向前扫描   * 如果该元素(已排序)大于新元素,将该元素移到下一位置    * 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置    * 将新元素插入到该位置中    * 重复步骤2    * @param numbers 待排序数组   */   public static void insertSort(int[] numbers)  {  int size = numbers.length;  int temp = 0 ;  int j = 0;    for(int i = 0 ; i < size ; i++)  {    temp = numbers[i];    //假如temp比前面的值小,则将前面的值后移    for(j = i ; j > 0 && temp < numbers[j-1] ; j --)    {    numbers[j] = numbers[j-1];    }    numbers[j] = temp;  }  }

  

4、效率:

时间复杂度:O(n^2).

 

 

三、希尔算法

1、基本思想:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

2、操作方法:

  1. 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  2. 按增量序列个数k,对序列进行k 趟排序;
  3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

希尔排序的示例:

 3、算法实现:

/**希尔排序的原理:根据需求,如果你想要结果从大到小排列,它会首先将数组进行分组,然后将较大值移到前面,较小值 * 移到后面,最后将整个数组进行插入排序,这样比起一开始就用插入排序减少了数据交换和移动的次数,可以说希尔排序是加强 * 版的插入排序 * 拿数组5, 2, 8, 9, 1, 3,4来说,数组长度为7,当increment为3时,数组分为两个序列 * 5,2,8和9,1,3,4,第一次排序,9和5比较,1和2比较,3和8比较,4和比其下标值小increment的数组值相比较 * 此例子是按照从大到小排列,所以大的会排在前面,第一次排序后数组为9, 2, 8, 5, 1, 3,4 * 第一次后increment的值变为3/2=1,此时对数组进行插入排序, *实现数组从大到小排 */  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、效率

 时间复杂度:O(n^2). 

 

 

4、各种算法的时间复杂度

  

   致谢:感谢您的耐心阅读!