排序算法进入到第7篇,这个也还是比较基础的一种,希尔排序,该排序算法,是依据该算法的发明人donald shell的名字命名的。1959年,shell基于传统的直接插入排序算法,对其性能做了下提升,其思路,主要是基于下面的原因进行的:

  1. 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
  2. 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

下面,我们就看看希尔排序,具体的实现思路如下:

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止

由上面的分析可知,希尔排序,其实是对原始待排序列的分组插入排序,这种分组,很巧妙,再次体现了分而治之这个思想的厉害。前面介绍过的排序:

排序算法<No.3>【桶排序】排序算法<No.4>【基数排序】都是分治思想的体现。

针对上面的实现思路,可以将其分解为如下的代码实现步骤:

1. 获取原始待排记录的元素个数len,并计算初始增量d=len/2

2. 通过d = d/2进行循环,对待排记录进行分组,d作为增量值,每间隔d的元素被划分到一组

3. 对2中每组元素进行直接插入排序算法进行排序

4. 重复2,3的过程,直到2中计算的增量d=1的这轮排序结束,程序退出,排序完成

下面,举个栗子来看看,希尔排序的实现过程吧,例如待排序列:59,48,75,107,86,23,37,59,65,14

相应的java代码实现如下:

/**
* @author "shihuc"
* @date 2017年4月9日
*/
package shellSort; import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner; /**
* @author "shihuc"
*
*/
public class Solution { /**
* @param args
*/
public static void main(String[] args) {
File file = new File("./src/shellSort/sample.txt");
Scanner sc = null;
try {
sc = new Scanner(file);
int N = sc.nextInt();
for (int i = ; i < N; i++) {
int S = sc.nextInt();
int A[] = new int[S];
for (int j = ; j < S; j++) {
A[j] = sc.nextInt();
}
shellSort(A);
print(A, i, "....");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (sc != null) {
sc.close();
}
} } /**
* 希尔排序的实现过程
*
* @param src 待排序的原始数列
*/
private static void shellSort(int src[]) { /*
* 实现步骤 (1)
* 获取原始待排记录的元素个数len,并计算初始增量d=len/2
*/
int d = src.length / ; /*
* 实现步骤(4)
*/
while (d > ) { /*
* 实现步骤(3)
* 通过增量d对待排序的数列进行分组,进行插入排序. 注意,排序中待比较的元素之间的差距是d
*/
for(int i = d; i<src.length; i=i+d){ int temp = src[i];
int j = i - d; /*
* 在获取参考值,也就待排序数列中当前位置的值,然后与其前面的需要排序的组内成员进行
* 插入排序。注意,这里的步长是d,和直接插入排序算法中的步长1的差异。认真想想,不难理解的。
*/
while(j >= && src[j] > temp){
src[j+d] = src[j];
j = j - d;
}
src[j+d] = temp;
} /*
* 实现步骤(2)
* 下面这个过程,其实就是不断迭代计算出新的增量d。
*/
d = d / ;
}
} /**
* 用来打印输出堆中的数据内容。
*
* @param A
* 堆对应的数组
* @param idx
* 当前是第几组待测试的数据
* @param info
* 打印中输出的特殊信息
*/
private static void print(int A[], int idx, String info) {
System.out.println(String.format("No. %02d %s ====================== ", idx, info));
for (int i = ; i < A.length; i++) {
System.out.print(A[i] + ", ");
}
System.out.println();
}
}

测试栗子文件内容如下:


测试运行的结果如下:

No.  .... ======================
, , , , , , , , , ,
No. .... ======================
, , , , , , ,
No. .... ======================
, , , , , , , , , ,
No. .... ======================
, , , , , , , , , , ,
No. .... ======================
, , , , , , ,
No. .... ======================
, , , , , , , , ,

其实,还是比较简单的,重点在于分组,插入排序的步长由原来的普通插入排序步长1变成了现在的d。

排序算法<No.7>【希尔排序】的更多相关文章

  1. 八大排序算法之二希尔排序(Shell Sort)

    希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进.希尔排序又叫缩小增量排序 基本思想: 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录 ...

  2. 排序算法入门之希尔排序(java实现)

    希尔排序是对插入排序的改进.插入排序是前面元素已经有序了,移动元素是一个一个一次往后移动,当插入的元素比前面排好序的所有元素都小时,则需要将前面所有元素都往后移动.希尔排序有了自己的增量,可以理解为插 ...

  3. python算法介绍:希尔排序

    python作为一种新的语言,在很多功能自然要比Java要好一些,也容易让人接受,而且不管您是成年人还是少儿都可以学习这个语言,今天就为大家来分享一个python算法教程之希尔排序,现在我们就来看看吧 ...

  4. python算法与数据结构-希尔排序算法(35)

    一.希尔排序的介绍 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是把记录按下标的一定增量分组,对每 ...

  5. C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序

    C# 插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 以下列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 高速排序 堆排序 归并排序 基数排序 希尔排序 ...

  6. Java常见排序算法之直接选择排序

    在学习算法的过程中,我们难免会接触很多和排序相关的算法.总而言之,对于任何编程人员来说,基本的排序算法是必须要掌握的. 从今天开始,我们将要进行基本的排序算法的讲解.Are you ready?Let ...

  7. Java排序算法之直接选择排序

    Java排序算法之直接选择排序 基本过程:假设一序列为R[0]~R[n-1],第一次用R[0]和R[1]~R[n-1]相比较,若小于R[0],则交换至R[0]位置上.第二次从R[1]~R[n-1]中选 ...

  8. Hark的数据结构与算法练习之希尔排序

    算法说明 希尔排序是插入排序的优化版. 插入排序的最坏时间复杂度是O(n2),但如果要排序的数组是一个几乎有序的数列,那么会降低有效的减低时间复杂度. 希尔排序的目的就是通过一个increment(增 ...

  9. C#算法基础之希尔排序

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. Java与算法之(10) - 希尔排序

    希尔排序是插入排序的一种,是直接插入排序的改进版本. 对于上节介绍的直接插入排序法,如果数据原来就已经按要求的顺序排列,则在排序过程中不需要进行数据移动操作,即可得到有序数列.但是,如果最初的数据是按 ...

随机推荐

  1. excel idea sql 操作

    1.excel  concatenate()函数中连接单元格中值拼接sql时,内容超长,把insert into.... values()前面的单独提出来,只在concatenate()中拼接valu ...

  2. 【Python】UI自动化-1

    一.安装selenium和环境配置 1 pip install selenium 2 三个驱动文件放到d:盘根目录 3 安装火狐版本33 4 安装插件:selenium ide\firebug\fir ...

  3. Oracle自我补充之OVER()函数介绍

    OVER(PARTITION BY)函数介绍 开窗函数               Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个组返 ...

  4. [转]TDD之Dummy Stub Fake Mock

    TDD之Dummy Stub Fake Mock 测试驱动大家都很熟悉了,这两天正好看了一个java的书,对TDD中的一些基本概念进行了复习,具体如下: Dummy An object that is ...

  5. SDM(Supervised Descent Method and its Applications to Face Alignment )

    sdm SDM 人脸对齐的核心内容很简单,就是特征到偏移量的映射:                                           Ix = R I 是特征,x是映射矩阵,R是偏移 ...

  6. Java中的初始化顺序

    一.在创建类时为成员变量赋值和在构造函数中的赋值的先后顺序  在未用构造器之前其实已经将类的字段进行了赋值只是在调用构造器时,又将类的字段进行了重新的赋值.如下: package com.cjm.in ...

  7. 【转】【计算机视觉】opencv靶标相机姿态解算2 根据四个特征点估计相机姿态 及 实时位姿估计与三维重建相机姿态

    https://blog.csdn.net/kyjl888/article/details/71305149

  8. 在城市后面加上省,市,区 以及将MySQL入库脚本封装成class

    在城市后面加省,市,区时,使用过滤器和for循环,if判断 一起使用.   自定义一个过滤器 def my_detail(val):                                  ...

  9. lesson9-小象学院cv

    www.sohu.com/a/159976204_717210 生成模型:基于联合概率~共生关系判别模型:基于条件概率~因果关系 生成模型之学习数据分布:1)概率密度函数估计 2)数据样本生成 模型目 ...

  10. php 中使用正则

    1.匹配一个由一个小写字母和一位数字组成的字符串,比如”z2″   用^[a-z][0-9]$ 2.当在一组方括号里使用^是,它表示“非”或“排除”的意思   比如要求第一个字符不能是数字:^[^0- ...