希尔排序 转载

希尔排序是对插入排序的一种改进算法,是一种分组插入排序,又称为缩小增量排序法。

希尔排序的时间复杂度与增量(即,步长gap)的选取有关。例如,当增量为1时,希尔排序退化成了直接插入排序,此时的时间复杂度为O(N²),而Hibbard增量(N/2)的希尔排序的时间复杂度为O(N3/2)。

(1)、主要步骤:

  1. 对一个数组长度为N的数组,取一个小于N的整数gap(gap称为步长)
  2. 根据该步长将数组分为若干个子数组,所有距离为gap的倍数的记录放在同一个子数组
  3. 对每个子数组进行插入排序
  4. 然后缩减gap的值,并重复上面的分组和排序
  5. 当gap==1时,整个数组就是有序的

(2)、演示过程:

下面以数列{80,30,60,40,20,10,50,70}为例,演示它的希尔排序过程。

第1趟:(gap=4)

当gap=4时,意味着将数列分为4个组: {80,20},{30,10},{60,50},{40,70}。 对应数列: {80,30,60,40,20,10,50,70}
对这4个组分别进行排序,排序结果: {20,80},{10,30},{50,60},{40,70}。 对应数列: {20,10,50,40,80,30,60,70}

第2趟:(gap=2)

当gap=2时,意味着将数列分为2个组:{20,50,80,60}, {10,40,30,70}。 对应数列: {20,10,50,40,80,30,60,70}
注意:{20,50,80,60}实际上有两个有序的数列{20,80}和{50,60}组成。
          {10,40,30,70}实际上有两个有序的数列{10,30}和{40,70}组成。
对这2个组分别进行排序,排序结果:{20,50,60,80}, {10,30,40,70}。 对应数列: {20,10,50,30,60,40,80,70}

第3趟:(gap=1)

当gap=1时,意味着将数列分为1个组:{20,10,50,30,60,40,80,70}
注意:{20,10,50,30,60,40,80,70}实际上有两个有序的数列{20,50,60,80}和{10,30,40,70}组成。
对这1个组分别进行排序,排序结果:{10,20,30,40,50,60,70,80}

public void sort(int[] arr) {
    // gap为步长,每次减为原来的一半。
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
        // 共gap个组,对每一组都执行直接插入排序
        for (int i = 0; i < gap; i++) {
            group_sort(arr, arr.length, i, gap);
        }
    }
}  

private void group_sort(int arr[], int n, int i, int gap) {
    for (int j = i + gap; j < n; j += gap) {
        // 如果a[j] < a[j-gap],则寻找a[j]位置,并将后面数据的位置都后移。
        if (arr[j] < arr[j - gap]) {
            int tmp = arr[j];
            int k = j - gap;
            while (k >= 0 && arr[k] > tmp) {
                arr[k + gap] = arr[k];
                k -= gap;
            }
            arr[k + gap] = tmp;
        }
    }
}  
时间: 2024-10-19 12:32:54

希尔排序 转载的相关文章

(转载)经典排序算法-希尔排序

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

排序算法之希尔排序

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

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

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

希尔排序(Shell&#39;s Sort)的C语言实现

原创文章,转载请注明来自钢铁侠Mac博客http://www.cnblogs.com/gangtiexia 希尔排序(Shell's Sort)又称“缩小增量排序”(Diminishing Increment Sort)的基本思想不断缩小步长后分组排序,具体步骤为 演示实例: C语言实现(编译器Dev-c++5.4.0,源代码后缀.cpp) 1 #include <stdio.h> 2 #define LEN 9 3 4 typedef float keyType; 5 6 typedef s

希尔排序与堆排序(Java版)

希尔排序 package ShellSort; import Utils.SortUtils; public class Demo { public static void shellSort(int[] a){ int temp,j; int increment = a.length; do{ increment = increment/3+1;//如果是直接插入排序,这里的increment都为1. //System.out.println(increment); for (int i =

JavaScript排序算法(希尔排序、快速排序、归并排序)

以var a = [4,2,6,3,1,9,5,7,8,0];为例子. 1.希尔排序. 希尔排序是在插入排序上面做的升级.是先跟距离较远的进行比较的一些方法. function shellsort(arr){ var i,k,j,len=arr.length,gap = Math.ceil(len/2),temp; while(gap>0){ for (var k = 0; k < gap; k++) { var tagArr = []; tagArr.push(arr[k]) for (i

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

希尔排序又叫做递减增量排序.在这种排序中,我们将设置一个步长(增量),我们在比较数据时根据增量去进行比较,这样我们的数据会一次性前进很多步,所以希尔排序的效率要比直接插入排序的效率高. 希尔排序的思想就是我们设置一个步长,然后我们根据这个步长进行划分子序列,得到子序列1,子序列2....,然后我们对每个子序列进行直接插入排序,我们也知道当整个数列基本有序的时候使用直接插入排序的效率是非常高的.然后我们缩小步长,则我们划分的子序列的个数越来越少,我们每个子序列中的数据越来越多,则我们基本有序的数据

常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)

一下是一些常见的排序算法: 交换元素(后面算法都有用到): // 交换元素 private static void swap(int[] a, int i, int j) { int temp; temp = a[i]; a[i] = a[j]; a[j] = temp; } 冒泡排序(有优化): // 冒泡排序(优化①,②,③,④) private static void bubbleSort(int[] a) { boolean flag = false;// ①表示整个序列是无序的 for

插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——C++实现

首先是算法实现文件Sort.h,代码如下: /* * 实现了八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 * 以及快速排序.归并排序.堆排序和LST基数排序 * @author gkh178 */ #include <iostream> template<class T> void swap_value(T &a, T &b) { T temp = a; a = b; b = temp; } //插入排序:时间复杂度o(n^2) template<