排序算法进入到第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. C# 子类父类方法同名,三种处理方式

    1.重载:参数数量或者参数类型不同(overloading ):2.重写:override 关键字重写父类方法,父类的方法是virtual 或 abstract修饰的, using System; c ...

  2. day 03 变量与基本数据类型

    变量的命名规范 一:变量命名的大前提,应该能够反映出变量值所记录内容 1:变量名只能由数字,字母,下划线组成 2:变量名不能以数字开头 3:变量名不能使用系统的关键字,不然可能会报错 二:变量名的命名 ...

  3. 适配手机端之 rem

    (function() { var psdWidth = 1080, maxRem = 100, ch = document.documentElement.clientHeight || docum ...

  4. 微软Power BI 每月功能更新系列——10月Power BI 新功能学习

    Power BI Desktop10月产品功能摘要 本月Power Plus Desktop的更新充满了整个产品的小型和大型改进.一个巨大的更新是Power BI服务支持我们的复合模型和聚合预览.这实 ...

  5. Spring Boot 揭秘与实战(二) 数据缓存篇 - Guava Cache

    文章目录 1. Guava Cache 集成 2. 个性化配置 3. 源代码 本文,讲解 Spring Boot 如何集成 Guava Cache,实现缓存. 在阅读「Spring Boot 揭秘与实 ...

  6. python time 时间处理

    a='2018-03-26 17:20:11' >>> print time.strftime("%Y%m%d", a)Traceback (most recen ...

  7. Linux more命令详解

    more功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回( ...

  8. Gym - 101889D:Daunting device (老司机树)

    题意:N个格子排出一排,开始格子颜色都是1:现在有M个操作: 或,把区间[L,R]颜色改为c: 或,查询一共有多少格子颜色为c. 最后求颜色最多的数量. 数据是随机的,且强制在线. 思路:ODT裸题. ...

  9. stringify在苹果电脑下的值不能为空

     sessionStorage.channel = JSON.stringify(  );苹果的safari不接受stringify里面为空 火桑飘零ご 2018/1/25 20:21:49 wind ...

  10. 动态规划-----hdu 1024 (区间连续和)

    给定一个长度为n的区间:求m段连续子区间的和 最大值(其中m段子区间互不相交) 思路: dp[i][j]: 前j个元素i个连续区间最大值 (重要 a[j]必须在最后一个区间内) 转移方程:dp[i][ ...