希尔(Shell)排序——改良的插入排序算法
2015-06-07 12:50
676 查看
转载自:http://blog.csdn.net/wuxianglong/article/details/6874403
希尔排序是插入排序中的一种,前面一篇文章(点击查看)中提到的插入排序算法准确的来说应该称为“直接插入排序算法”,而这里介绍的希尔排序算法是对直接插入排序算法改进之后形成的一种算法,该算法是由D.L
Shell于1959年提出的,它也因此而得名,又称缩小增量排序算法。
基本思想
设初始序列有n个元素,选定一个小于n大于或等于1的整数gap作为间隔,将全部元素分成gap个子序列,所有距离为gap的元素放在同一个子序列中,在每个子序列中分别采用直接插入算法进行排序;然后缩小间隔gap,如令gap=gap/2,重复上面的子序列划分和子序列排序动作;直到最后去gap=1,将所有的元素放到一个序列中为止。
简单示例
初始序列:21 25 49 25 16 8
第一步:
第二步:
第三步:
算法说明
开始时gap的值较大,子序列中的元素较少,排序速度比较快;随着排序进展,gap的值逐渐减小,子序列中的元素增多,不过由于前面排序工作的基础,大多数元素已基本有序,所以排序速度依然是比较快的。
对于gap值的取法有很多种。最初Shell提出取gap=n/2,gap=gap/2,直到gap=1。后来Knuth提出取gap=gap/3+1,另外还有人认为gap都去奇数比较好,也有人说让各个gap值互质为好。另外,由上面的实例可以看出:该算法是不稳定的算法。
算法分析
对特定的待排序序列,可以准确的估算元素的比较次数和移动次数;但是,想要弄清楚元素比较次数和移动次数与增量选择之间的依赖关系,并给出完整的数学分析,还没有人能够做到。另外,由上面的实例可以看出:该算法是不稳定的算法。
算法实现
C语言:
[cpp] view
plaincopyprint?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t; t = x; x = y; y = t;}
void shellsort(int[]);
int main(void) {
int number[MAX] = {0};
int i;
srand(time(NULL));
printf("排序前:");
for(i = 0; i < MAX; i++) {
number[i] = rand() % 100;
printf("%d ", number[i]);
}
shellsort(number);
return 0;
}
void shellsort(int number[]) {
int i, j, k, gap, t;
gap = MAX / 2;
while(gap > 0) {
for(k = 0; k < gap; k++) {
for(i = k+gap; i < MAX; i+=gap) {
for(j = i - gap; j >= k; j-=gap) {
if(number[j] > number[j+gap]) {
SWAP(number[j], number[j+gap]);
}
else
break;
}
}
}
printf("\ngap = %d:", gap);
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
gap /= 2;
}
}
JAVA语言:
[java] view
plaincopyprint?
public class ShellSort {
public static void sort(int[] number) {
int gap = number.length / 2;
while(gap > 0) {
for(int k = 0; k < gap; k++) {
for(int i = k+gap; i < number.length; i+=gap) {
for(int j = i - gap; j >= k; j-=gap) {
if(number[j] > number[j+gap]) {
swap(number, j, j+gap);
}
else
break;
}
}
}
gap /= 2;
}
}
private static void swap(int[] number, int i, int j) {
int t;
t = number[i];
number[i] = number[j];
number[j] = t;
}
}
THE END!
希尔排序是插入排序中的一种,前面一篇文章(点击查看)中提到的插入排序算法准确的来说应该称为“直接插入排序算法”,而这里介绍的希尔排序算法是对直接插入排序算法改进之后形成的一种算法,该算法是由D.L
Shell于1959年提出的,它也因此而得名,又称缩小增量排序算法。
基本思想
设初始序列有n个元素,选定一个小于n大于或等于1的整数gap作为间隔,将全部元素分成gap个子序列,所有距离为gap的元素放在同一个子序列中,在每个子序列中分别采用直接插入算法进行排序;然后缩小间隔gap,如令gap=gap/2,重复上面的子序列划分和子序列排序动作;直到最后去gap=1,将所有的元素放到一个序列中为止。
简单示例
初始序列:21 25 49 25 16 8
第一步:
第二步:
第三步:
算法说明
开始时gap的值较大,子序列中的元素较少,排序速度比较快;随着排序进展,gap的值逐渐减小,子序列中的元素增多,不过由于前面排序工作的基础,大多数元素已基本有序,所以排序速度依然是比较快的。
对于gap值的取法有很多种。最初Shell提出取gap=n/2,gap=gap/2,直到gap=1。后来Knuth提出取gap=gap/3+1,另外还有人认为gap都去奇数比较好,也有人说让各个gap值互质为好。另外,由上面的实例可以看出:该算法是不稳定的算法。
算法分析
对特定的待排序序列,可以准确的估算元素的比较次数和移动次数;但是,想要弄清楚元素比较次数和移动次数与增量选择之间的依赖关系,并给出完整的数学分析,还没有人能够做到。另外,由上面的实例可以看出:该算法是不稳定的算法。
算法实现
C语言:
[cpp] view
plaincopyprint?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t; t = x; x = y; y = t;}
void shellsort(int[]);
int main(void) {
int number[MAX] = {0};
int i;
srand(time(NULL));
printf("排序前:");
for(i = 0; i < MAX; i++) {
number[i] = rand() % 100;
printf("%d ", number[i]);
}
shellsort(number);
return 0;
}
void shellsort(int number[]) {
int i, j, k, gap, t;
gap = MAX / 2;
while(gap > 0) {
for(k = 0; k < gap; k++) {
for(i = k+gap; i < MAX; i+=gap) {
for(j = i - gap; j >= k; j-=gap) {
if(number[j] > number[j+gap]) {
SWAP(number[j], number[j+gap]);
}
else
break;
}
}
}
printf("\ngap = %d:", gap);
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
gap /= 2;
}
}
JAVA语言:
[java] view
plaincopyprint?
public class ShellSort {
public static void sort(int[] number) {
int gap = number.length / 2;
while(gap > 0) {
for(int k = 0; k < gap; k++) {
for(int i = k+gap; i < number.length; i+=gap) {
for(int j = i - gap; j >= k; j-=gap) {
if(number[j] > number[j+gap]) {
swap(number, j, j+gap);
}
else
break;
}
}
}
gap /= 2;
}
}
private static void swap(int[] number, int i, int j) {
int t;
t = number[i];
number[i] = number[j];
number[j] = t;
}
}
THE END!
相关文章推荐
- [管理篇6]使用Linux Shell管理OpenStack的虚拟机——批量创建、开启、关闭虚拟机
- shell数值计算
- shell中如何判断一个变量是否为空
- Linux 中 shell 变量 $#,$@,$0,$1,$2 的含义解释:
- Shellcode的编写
- lvs相关4道shell编程题
- 揭开Shellcode的神秘面纱
- wince6.0 中出现缺少aygshell.h
- load和磁盘占用shell
- /bin/bash^M: bad interpreter: No such file or directory
- shell脚本(三)
- shell脚本(二)
- shell脚本(一)
- 四、文件名置换
- 鸟书shell 学习笔记(一) shell专注于概念和命令
- 使用Xshell连接Ubuntu
- shell参数 传递
- Linux and Shell
- 在Windows中如何用SSH_Client_Shell与Linux实现通讯以及共享
- mysql下通过shell脚本插入数据