
正文
Go语言希尔排序 希尔排序 java
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
什么是希尔排序法
基本思想:
将整个无序序列分割成若干小Go语言希尔排序的子序列分别进行插入排序。
序列分割方法:将相隔某个增量h的元素构成一个子序列。在排序过程中Go语言希尔排序,逐次减小这个增量Go语言希尔排序,最后当h减到1时Go语言希尔排序,进行一次插入排序Go语言希尔排序,排序就完成。增量序列一般采用:ht=2t-1,1≤t≤[log2n],其中n为待排序序列的长度。
void prshl(p,n)
int n;double p[];
{
int k,j,i;
double t;
k=n/2;
while(k0)
{
for(j=k;j=n-1;j++)
{
t=p[j];i=j-k;
while((i=0)(p[i]t))
{
p[i+k]=p[i];i=i-k;
}
p[i+k]=t;
}
k=k/2;
}
return;
}
希尔排序(缩小增量法)
属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序
排序过程:先取一个正整数d1n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;然后取d2d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止
初始:d=5
49 38 65 97 76 13 27 49* 55 04
|---------------|
38 27
|--------------|
65 49*
|--------------|
97 55
|---------------|
|76-------------04|
一趟结果
d=3 13 27 49*55 04 49 38 65 97 76
|--------|--------|----------|
27 04 65
|--------|-------|
49* 49 97
|--------|---------|
二趟结果
13 04 49*38 27 49 66 65 97 76
d=1
三趟结果
04 13 27 38 49*49 55 65 76 97
相关问答
Q1: 希尔排序法中距离为d是什么意思
属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序
排序过程:先取一个正整数d1n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;然后取d2d1,重复上述分组和排序操作;直至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。
希尔排序是不稳定的。
=====================================================
*/
void shell_sort(int *x, int n)
{
int h, j, k, t;
for (h=n/2; h0; h=h/2) /*控制增量*/
{
for (j=h; jn; j++) /*这个实际上就是上面的直接插入排序*/
{
t = *(x+j);
for (k=j-h; (k=0 t*(x+k)); k-=h)
{
*(x+k+h) = *(x+k);
}
*(x+k+h) = t;
}
}
}
void main()
{
#define MAX 16
int *p, i, a[MAX];
/*录入测试数据*/
/*
p = a;
printf("Input %d number for sorting :\n",MAX);
for (i=0; iMAX; i++)
{
scanf("%d",p++);
}
*可以自己输入数据
*/
a[] = {503,17,512,908,170,897,275,653,462,154,509,612,677,765,703,94};
printf("\n");
//503,17,512,908,170,897,275,653,462,154,509,612,677,765,703,94
/*测试排序*/
p = a;
shell_sort(p,MAX);
/**/
for (p=a, i=0; iMAX; i++)
{
printf("%d ",*p++);
}
printf("\n");
system("pause");
}
pascal算法程序:
program xepx;
const n=7;
type
arr=array[1..n] of integer;
var
a:arr;
i,j,t,d:integer;
bool:boolean;
begin
write('input data:');
for i:=1 to n do read(a);
writeln;
d:=n;
while d1 do
begin
d:=d div 2;
for j:=d+1 to n do
begin
t:=a[j];i:=j-d;
while (i0) and (at) do
begin a[i+d]:=a;i:=i-d;end;
a[i+d]:=t;
end;
end;
write('output data:');
for i:=1 to n do write(a:6);
writeln;
end.
Q2: 希尔排序怎么排啊
下标 0 1 2 3 4 5 6 7 8 9
数组 49 38 65 97 26 13 27 50 55 4 (原数组)
增量=5, [0]=49与[5]=13为一组,互换为 13 49 (排序是从小到大)
[1]=38与[6]=27为一组,互换为 27 38
[2]=65与[7]=50为一组,互换为 50 65
[3]=97与[8]=55为一组,互换为 55 97
[4]=26与[9]=4 为一组,互换为 4 26
增量=5的排序结果是: 13 27 50 55 4 49 38 65 97 26
下标 0 1 2 3 4 5 6 7 8 9
数组 13 27 50 55 4 49 38 65 97 26 (第一趟之后)
增量=2, [0]=13,[2]=50,[4]=4,[6]=38,[8]=97为一组,
互换之后,[0]=4,[2]=13,[4]=38,[6]=50,[8]=97
[1]=27,[3]=55,[5]=49,[7]=65,[9]=26为一组,
互换之后,[1]=26,[3]=27,[5]=49,[7]=55,[9]=65
增量=2的排序结果是: 4 26 13 27 38 49 50 55 97 65
下标 0 1 2 3 4 5 6 7 8 9
数组 4 26 13 27 38 49 50 55 97 65 (第二趟之后)
增量=1, 数组里的10个数据作为一组,其中,
[1]=26有[2]=13互换为 13 26
[8]=97与[9]=65互换为 65 97
增量=1的排序结果是: 4 13 26 27 38 49 50 55 65 97
// C语言测试代码
// 希尔排序法 (自定增量)
#include stdio.h
#include stdlib.h
void printData(int data[],int n) //打印数组
{
int i;
for(i=0;in;i++)
{
printf("%d ",data[i]);
}
printf("\n");
}
//希尔排序(从小到大)
void shell(int data[],int count)
{
int offset_a[3]={5,2,1}; //每一趟的增量
int len;
int pos;
int offset;
int i,j;
int temp;
len=sizeof(offset_a)/sizeof(int);
for(i=0;ilen;i++)
{
offset=offset_a[i];
for(j=offset;jcount;j++)
{
temp=data[j];
pos=j-offset;
while(tempdata[pos] pos=0 j=count)
{
data[pos+offset]=data[pos];
pos=pos-offset;
}
data[pos+offset]=temp;
}
printf("增量=%d,排序结果: ",offset);
printData(data,count);
}
}
int main(void)
{
int data[]={49,38,65,97,26,13,27,50,55,4};
int count;
count=sizeof(data)/sizeof(int);
printf("原数组: ");
printData(data,count);
shell(data,count);
printf("\n最后的排序结果: ");
printData(data,count);
return 0;
}
Q3: 谁知道什么叫“谢尔排序”(也叫“希尔排序”)
希尔排序
日期:2005-5-25 10:45:55 来源: 编辑: 175
它的基本思想是:先将整个待排记录序列分割成为若干子序列分别进行直接插入排 序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
在希尔排序中,子序列的构成不是简单地“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。如在第一趟排序时的增量为7,即将相隔为7的元素编成一组进行直接插入排序。第二趟排序时的增量为3,增量进一步缩小。由于在这两趟的插入排序中在子序列中逆序的关键字是跳跃式地移动,从而使得在进行最后一趟增量为1的插入排序时,序列已基本有序,只要作少量比较和移动即可完成排序,因此希尔排序的时间复杂度较直接插入排序低。
下面用算法语言描述的希尔排序:
希尔排序中增量序列的选取是一个复杂的问题,涉及到一些数学上尚未解决的难题。我们不想加以详细讨论。到目前仅得出部分结论:如当增量序列为d[k]=2t-k+l -1时,希尔排序的运行时间为O(n3/2),其中1≤k≤t≤└log2(n+1)┘。增量序列还可以有各种取法, 如d[k]=2t-k,(d=…,9,5,3,2,1)。但请注意:应使增量序列中的值没有除1之外的公因子,并且最后一个增量值必须等于1。
Q4: 希尔排序图解流程图
.example-btn{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.example-btn:hover{color:#fff;background-color:#47a447;border-color:#398439}.example-btn:active{background-image:none}div.example{width:98%;color:#000;background-color:#f6f4f0;background-color:#d0e69c;background-color:#dcecb5;background-color:#e5eecc;margin:0 0 5px 0;padding:5px;border:1px solid #d4d4d4;background-image:-webkit-linear-gradient(#fff,#e5eecc 100px);background-image:linear-gradient(#fff,#e5eecc 100px)}div.example_code{line-height:1.4em;width:98%;background-color:#fff;padding:5px;border:1px solid #d4d4d4;font-size:110%;font-family:Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;word-break:break-all;word-wrap:break-word}div.example_result{background-color:#fff;padding:4px;border:1px solid #d4d4d4;width:98%}div.code{width:98%;border:1px solid #d4d4d4;background-color:#f6f4f0;color:#444;padding:5px;margin:0}div.code div{font-size:110%}div.code div,div.code p,div.example_code p{font-family:"courier new"}pre{margin:15px auto;font:12px/20px Menlo,Monaco,Consolas,"Andale Mono","lucida console","Courier New",monospace;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;border:1px solid #ddd;border-left-width:4px;padding:10px 15px} 排序算法是《数据结构与算法》中最基本Go语言希尔排序的算法之一。排序算法可以分为内部排序和外部排序Go语言希尔排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。以下是希尔排序算法:
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率Go语言希尔排序; 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位Go语言希尔排序;
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
1. 算法步骤
选择一个增量序列 t1,t2,……,tk,其中 ti tj, tk = 1;
按增量序列个数 k,对序列进行 k 趟排序;
每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
2. 动图演示
代码实现 JavaScript 实例 function shellSort ( arr ) {
var len = arr. length ,
temp ,
gap = 1 ;
while ( gap 0 ; gap = Math . floor ( gap / 3 ) ) {
for ( var i = gap ; i = 0 arr [ j ] temp ; j -= gap ) {
arr [ j + gap ] = arr [ j ] ;
}
arr [ j + gap ] = temp ;
}
}
return arr ;
}
Python 实例 def shellSort ( arr ) :
import math
gap = 1
while ( gap 0 :
for i in range ( gap , len ( arr ) ) :
temp = arr [ i ]
j = i-gap
while j = 0 and arr [ j ] temp:
arr [ j+gap ] = arr [ j ]
j- = gap
arr [ j+gap ] = temp
gap = math . floor ( gap/ 3 )
return arr
Go 实例 func shellSort ( arr [] int ) [] int {
length := len ( arr )
gap := 1
for gap length / 3 {
gap = gap * 3 + 1
}
for gap 0 {
for i := gap ; i length ; i ++ {
temp := arr [ i ]
j := i - gap
for j = 0 arr [ j ] temp {
arr [ j + gap ] = arr [ j ]
j -= gap
}
arr [ j + gap ] = temp
}
gap = gap / 3
}
return arr
}
Java 实例 public static void shellSort ( int [ ] arr ) {
int length = arr. length ;
int temp ;
for ( int step = length / 2 ; step = 1 ; step /= 2 ) {
for ( int i = step ; i = 0 arr [ j ] temp ) {
arr [ j + step ] = arr [ j ] ;
j -= step ;
}
arr [ j + step ] = temp ;
}
}
}
PHP 实例 function shellSort ( $arr )
{
$len = count ( $arr ) ;
$temp = 0 ;
$gap = 1 ;
while ( $gap 0 ; $gap = floor ( $gap / 3 ) ) {
for ( $i = $gap ; $i = 0 $arr [ $j ] $temp ; $j -= $gap ) {
$arr [ $j + $gap ] = $arr [ $j ] ;
}
$arr [ $j + $gap ] = $temp ;
}
}
return $arr ;
}
C 实例 void shell_sort ( int arr [ ] , int len ) {
int gap , i , j ;
int temp ;
for ( gap = len 1 ; gap 0 ; gap = 1 )
for ( i = gap ; i = 0 arr [ j ] temp ; j -= gap )
arr [ j + gap ] = arr [ j ] ;
arr [ j + gap ] = temp ;
}
}
C++ 实例 template
void shell_sort ( T array [ ] , int length ) {
int h = 1 ;
while ( h = 1 ) {
for ( int i = h ; i = h array [ j ] 0) { for (int i = gap; i arr.Length; i++) { int tmp = arr[i]; int j = i - gap; while (j = 0 arr[j] tmp) { arr[j + gap] = arr[j]; j -= gap; } arr[j + gap] = tmp; } gap /= 3; } } 以上为希尔排序算法详细介绍,插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等排序算法各有优缺点,用一张图概括:
关于时间复杂度
平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。
线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序;
O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序
线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。
关于稳定性
稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。
不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。
名词解释:
n:数据规模
k:"桶"的个数
In-place:占用常数内存,不占用额外内存
Out-place:占用额外内存
稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同
关于Go语言希尔排序和希尔排序 java的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。






