希尔排序总结

数据结构之排序算法——希尔排序

代码很多地方借鉴了  http://my.csdn.net/MoreWindows 他的思想,

本人认为该作者已经写的很好了,只是在他的基础上加入了一些自己的理解和说明

如果涉及到版权的问题,请联系我的邮箱,我会尽快删除

希尔排序想关链接:

维基百科:https://zh.wikipedia.org/wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F#C.E8.AA.9E.E8.A8.80

百度百科:http://baike.baidu.com/view/178698.htm

参考博客 :http://blog.csdn.net/morewindows/article/details/6668714

希尔排序:其实就是分组的插入排序

希尔排序基本思想是:

在无序的数组中定义一个增量,然后用增量将数组分成几个部分,每个部分进行插入排序,然后减少增量的大小,继续进行插入排序,直到最后增量为1,进行最后的排序操作

我看到两种增量的定义方式

  第一种是 先将数组的长度赋值3/1 +1给增量,然后让增量等于自己的3/1 +1,保证每次增量的大小不小于 1,结束条件是增量不小于 1

    注意: 使用这个方式一定要注意增量是永远大于等于1 的,因此一个好的处理方式是使用do {}while();

  第二种是将数组将数组的长度除以2赋值给增量,然后让增量等于自己的1/2 结束条件是增量小于1

其实增量的定义只是在分组的时候,确定每个组数据的规模,没什么需要去深究的!

利用第一个增量方式的源码:

void Shell_Sort(int array[], int arrayLen)

{

// 定义一个增量

int Incremental = arrayLen;

do

{

Incremental = Incremental / 3 + 1;

for (int i = 0; i < Incremental;++ i)

{

for (int j = i + Incremental; j < arrayLen; j += Incremental)

{

// 从大到小

if (array[j - Incremental] < array[j])

{

int InsertNum = array[j];

int k = j-Incremental;

while (k >= 0 && array[k] < InsertNum)

{

array[k+ Incremental] = array[k];

k -= Incremental;

}

array[k + Incremental] = InsertNum;

}

}

}

} while (Incremental > 1);

}

利用第二个增量方式的源码

void Shell_Sort(int array[], int arrayLen)

{

// 确认每次增量的大小

for (int Incremental = arrayLen / 2; Incremental > 0; Incremental /= 2)

{

// 分组进行插入排序

for (int i = 0; i < Incremental; ++ i)

{

for (int j = i + Incremental; j < arrayLen; j+= Incremental)

{

// 从大到小

if (array[j - Incremental] < array[j])

{

int InsertNum = array[j];

int k = j-Incremental;

while (k >= 0 && array[k] < InsertNum)

{

array[k + Incremental] = array[k];

k -= Incremental;

}

array[k + Incremental] = InsertNum;

}

}

}

}

}

针对第二种方案的一些优化:主要是对开始位置的优化,在插入排序中,每次查找与前面的大小关系时都从已经有序的位置开始,在希尔排序的每个分组里面我们也可以这样认为,这样,我们每次从增量开始,寻找增量和它前面的分组的数的关系,然后进行大小的调整

源码如下

void Shell_Sort(int array[], int arrayLen)

{

for (int Incremental = arrayLen / 2; Incremental > 0; Incremental /= 2)

{

// 分组进行插入排序

for (int i = Incremental; i < arrayLen; ++ i)

{

// 由大到小

if (array[i] > array[i - Incremental])

{

int InsertNum = array[i];

int j = i - Incremental;

// 注意分析 j 和 InsertNum 代表的数据的位置,结合整体的大小顺序

while (j >= 0 && array[j] < InsertNum)

{

array[j + Incremental] = array[j];

j -= Incremental;

}

array[j + Incremental] = InsertNum;

}

}

}

}

还可以进一步把第二次优化的的最后的一个for(){}和下面的if()语句合并,然后用数据的移动来代替,查找插入位置

源码:

void Shell_Sort(int array[], int arrayLen)

{

for (int Incremental = arrayLen / 2; Incremental > 0; Incremental /= 2)

{

// 分组进行插入排序

for (int i = Incremental; i < arrayLen; ++i)

{

for (int j = i - Incremental; j >=0 && array[j] < array[j + Incremental]; j -= Incremental)

{

Swap_IntVal(array + j, array + j + Incremental);

}

}

}

}

时间: 2024-12-29 12:10:16

希尔排序总结的相关文章

算法 希尔排序

希尔排序 Shell Sort 介绍: 希尔排序(Shell Sort)也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序.因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率比直接插入排序有较大提高. 执行流程: 首先

算法学习#09--用简单的思维理解选择、插入、冒泡和希尔排序

选择排序 1.原理 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾.以此类推,直到所有元素均排序完毕. 2.特点 ①运行时间与输入无关. 无论输入初始状态如何,是否有序,都需要遍历数组来找出最小的元素.其他算法则更善于利用输入的初始状态来优化时间. ②数据移动次数最小. 如果某个元素位于正确的最终位置上,则它不会被移动.选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进

奔走在算法的大路上(一)排序之希尔排序

希尔排序是插入排序的一种更高效的改进版本.它的作法不是每次一个元素挨一个元素的比较.而是初期选用大跨步(增量较大)间隔比较,使记录跳跃式接近它的排序位置:然后增量缩小:最后增量为 1 ,这样记录移动次数大大减少,提高了排序效率.希尔排序对增量序列的选择没有严格规定. 希尔排序最关键的是选对增量,关于增量的选择,建议参考:http://zh.wikipedia.org/wiki/希尔排序  中的步长序列. 希尔排序的核心思想是:由一定规则将带排序的长序列切割成多个子序列,子序列进行内部插入排序,如

排序算法——希尔排序

希尔排序 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. 该方法因DL.Shell于1959年提出而得名. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多, 当增量减至1时,整个文件恰被分成一组,算法便终止. 代码实现 void shellsort(int a[],int n) { int gap=0,i=0,temp=0,j=0; for(

排序算法之希尔排序

文章转载自http://www.cnblogs.com/chengxiao/ 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一.本文会以图解的方式详细介绍希尔排序的基本思想及其代码实现. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组

算法系列【希尔排序】篇

常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等.用一张图概括: 关于时间复杂度: 1.     平方阶 (O(n2)) 排序各类简单排序:直接插入.直接选择和冒泡排序. 2.     线性对数阶 (O(nlog2n)) 排序快速排序.堆排序和归并排序: 3.     O(n1+§))排序,§ 是介于 0 和 1 之间的常数.希尔排序 4.     线性阶 (O(n)) 排序基数排序,此外还有桶.箱排序. 关于稳定性: 稳定的排序算法:冒泡排序

希尔排序算法实现(1099)

p { margin-bottom: 0.25cm; line-height: 120% } 描述 编程实现希尔排序算法,按照非递减排序,测试数据为整数. input 第一行是待排序数据元素的个数n: 第二行是待排序的数据元素. output 一趟希尔排序后的结果. 样例输入 10 50 36 41 19 23 4 20 18 12 22 样例输出 4 20 18 12 22 50 36 41 19 23 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一

希尔排序Shell sort

希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分, 第一部分,希尔排序介绍 第二部分,如何选取关键字,选取关键字是希尔排序的关键 第一块希尔排序介绍 准备待排数组[6 2 4 1 5 9] 首先需要选取关键字,例如关键是3和1(第一步分成三组,第二步分成一组),那么待排数组分成了以下三个虚拟组: [6 1]一组 [2 5]二组 [4 9]三组 看仔细啊,不是临近的两个数字分组,而是3(分成了三组)的倍数的数字分成了一组, 就是每隔3个数取一个,每隔三个再取一个,这样取出来的数

希尔排序法(缩小增量法)

2016-10-25 16:51:49 首先,要明白希尔排序法是什么.它是一种改进版的直接插入法,它是将整个无序列分割成若干小的子序列分别进行插入排序的方法. 1 #include<stdio.h> 2 3 //希尔排序法 4 void shell_sort(int a[],int n); 5 int main() 6 { 7 int i; 8 int a[6]; 9 printf("please enter five numbers:\n"); 10 for(i=1;i&

希尔排序(shell)理论---不含源码

|   版权声明:本文为博主原创文章,未经博主允许不得转载. 希尔排序,是一个缩小增量排序.它根据步长来进行排序,步长不同可能会产生不同的序列,但是他们的最终结果是相同的,希尔排序的官方理论难以理解,这里就用非官方的解释来阐述. 原理: >1.加入有n个节点的序列,假设希尔排序的步长i,那么我们第一步就是将这n个节点,每隔i个座位为一组,如下所示(步长i要取好): [n1, n1+i] [n2, ni+2] [...........] [nx, nn] >2.然后每一组两两比较,如n1和n1+