希尔排序

基本思想

  希尔排序基本思想:  先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。  该方法实质上是一种分组插入方法。  给定实例的shell排序的排序过程  假设待排序文件有10个记录,其关键字分别是: 

 49,38,65,97,76,13,27,49,55,04。  

增量序列的取值依次为: 

 5,3,1

缩小增量法  

属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序  

排序过程:

先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;然后取d2<d1,

重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止   

初始:d=5   49 38 65 97 76 13 27 49* 55 04  

 49 13   |-------------------|  

 38 27   |-------------------|   

65 49*   |-------------------|   

97 55   |-------------------|   

76 04   |-------------------|   

一趟结果   13 27 49* 55 04 49 38 65 97 76  

 d=3   

13 27 49* 55 04 49 38 65 97 76   

13 55 38 76   |------------|------------|------------|   

27 04 65        |------------|------------|  


49* 49 97      |------------|------------|   


二趟结果   

13 04 49* 38 27 49 55 65 97 76  

 d=1   

13 04 49* 38 27 49 55 65 97 76  

|----|----|----|----|----|----|----|----|----|   

三趟结果   

04 13 27 38 49* 49 55 65 76 97  

 --------------------------------------------------------------------------------------------   

例如

对503,17,512,908,170,897,275,653,462,154,509,612,677,765,703,94排序的C语言算法   ================================================  

 功能:希尔排序   输入:数组名称(也就是数组首地址)、数组中元素个数  

 ================================================   */   /*   

====================================================   

算法思想简单描述:   

在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,   

并且对插入下一个数没有提供任何帮助。如果比较相隔较远距离(称为   增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除   多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现 了这一思想。

算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,

在每组中再进行排序。当增量减到1时,整个要排序的数被分成   一组,排序完成。   下面的函数是一个希尔排序算法的一个实现,初次取序列的一半为增量,   

以后每次减半,直到增量为1。   希尔排序是不稳定的。

下面是java 实现


public class Test {  

public static int[] a = { 10, 32, 1, 9, 5, 7, 12, 0, 4, 3 };  

public static void main(String args[]) {  

int i; // 循环计数变量  

int Index = a.length;// 数据索引变量 

 System.out.print("排序前: ");  

for (i = 0; i < Index - 1; i++)  

System.out.printf("%3s ", a[i]); 

 System.out.println("");  

ShellSort(Index - 1); // 选择排序  

// 排序后结果  

System.out.print("排序后: ");  

for (i = 0; i < Index - 1; i++)  

System.out.printf("%3s ", a[i]);  

System.out.println("");  

}  

public static void ShellSort(int Index) { 

 int i, j, k; // 循环计数变量  

int Temp; // 暂存变量  

boolean Change; // 数据是否改变 

 int DataLength; // 分割集合的间隔长度 

 int Pointer; // 进行处理的位置 

 DataLength = (int) Index / 2; // 初始集合间隔长度 

 while (DataLength != 0) // 数列仍可进行分割 

 { 

 // 对各个集合进行处理  

for (j = DataLength; j < Index; j++) { 

Change = false;  

Temp = a[j]; // 暂存Data[j]的值,待交换值时用

  Pointer = j - DataLength; // 计算进行处理的位置 

 // 进行集合内数值的比较与交换值 

 while (Temp < a[Pointer] && Pointer >= 0 && Pointer <= Index) {  

a[Pointer + DataLength] = a[Pointer]; 

 // 计算下一个欲进行处理的位置  

Pointer = Pointer - DataLength; 

Change = true;  

if (Pointer < 0 || Pointer > Index)  break;  } 

 // 与最后的数值交换  

a[Pointer + DataLength] = Temp;  

if (Change) { 

 // 打印目前排序结果  

System.out.print("排序中: ");  

for (k = 0; k < Index; k++)  

System.out.printf("%3s ", a[k]);  

System.out.println("");  

}  }  

DataLength = DataLength / 2; // 计算下次分割的间隔长度 

 }  

}  

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值