数据结构 排序(希尔排序)

//排序--希尔排序法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>

/*
强调:网上,书上的希尔排序法都有问题
希尔排序并非按一个增量d,将一个数组分成若干小的数组,对每个数组进行插入排序,这个理论不适用下面的代码
也不符合希尔排序的时间复杂度

真正的希尔排序步骤
第一步,通过业界常规 d = 数组长度 / 3 + 1;  求出增量d
第二步:取数组第一个元素,按照增量d的间隔 组成一个新的数组,对这个数组进行增量排序
第三步:再次获取增量d  d = d / 3 + 1; 还是获取数组的第一个元素  按照增量d的间隔 组成一个新的数组,对这个数组进行增量排序
第四步:重复第三步  

注意:①每次插入排序的都是第一个元素对应的新数组,没有对第二个元素对应的数组(或者第n个元素对应的数组)进行排序
②希尔排序当d=1的时候  仍然执行了一轮,当d=1 其实就是对整个数组进行一次插入排序

我个人感觉这比插入排序还多了几步

*/

//位置调换
void MySwap(int *arr,int a,int b){
    int temp = arr[a];
    arr[a] = arr[b];
    arr[b] = temp;
}

//打印数组
void Print(int * arr, int num){
    if (arr == NULL)
    {
        printf("传入参数不可以为空!\n");
        return;
    }
    int i = 0;
    for (int i = 0; i < num; i++)
    {
        printf("%5d", *(arr + i));
    }
    printf("\n");
}

//希尔排序
void ShellSort(int *arr,int len){
    //定义每次间隔元素的个数
    int gap = len;
    int i = 0,j=0,temp=0,k=0;
    do
    {
        //业界统一实验的间隔将是数组长度的1/3  平均最好情况 经过若干次后,收敛为1
        gap = gap / 3 + 1;
        //由第一组数据加上d1  获取第一组数据中的每个元素在后面组中对应位置的数据
        for (i = gap; i < len; i += gap)
        {
            k = i;
            temp = arr[k];
            //此时  每间隔d1的元素正好是i循环的数组  对这个新数组中的元素执行插入排序
            //i-gap是子数组的最大下标  现在要插入的元素的下标是i
            for (j = i - gap; j >= 0 && arr[j] >= temp; j -= gap)
            {
                //插入排序
                arr[j + gap] = arr[j];
                k = j;
            }
            arr[k] = temp;
        }
        //打印数组
        printf("\n第%d轮\n",gap);
        Print(arr, len);
    } while (gap>1);
}

void ShellSort2(int *arr, int len){
    //定义每次间隔元素的个数
    int gap = len;
    int i = 0, j = 0, temp = 0, k = 0,m=0;
    do
    {
        //业界统一实验的间隔将是数组长度的1/3  平均最好情况 经过若干次后,收敛为1
        gap = gap / 3 + 1;
        for ( m = 0; m < gap; m++)
        {
            //由第一组数据加上d1  获取第一组数据中的每个元素在后面组中对应位置的数据
            for (i = gap+m; i < len; i += gap)
            {
                k = i;
                temp = arr[k];
                //此时  每间隔d1的元素正好是i循环的数组  对这个新数组中的元素执行插入排序
                //i-gap是子数组的最大下标  现在要插入的元素的下标是i
                for (j = i - gap; j >= 0 && arr[j] >= temp; j -= gap)
                {
                    //插入排序
                    arr[j + gap] = arr[j];
                    k = j;
                }
                arr[k] = temp;
            }
        }
        //打印数组
        printf("\n第%d轮\n", gap);
        Print(arr, len);
    } while (gap>1);
}

void Test(){
    int i = 0;
    int arr[10] = { 0 };
    //定义时间类型变量
    time_t ts;
    //生成随机数种子
    srand((unsigned int)time(&ts));
    for (i = 0; i < 10; i++)
    {
        arr[i] = (int)(rand() % 100);
    }
    //打印数组
    printf("\n原始数据----\n");
    Print(arr, 10);
    //希尔排序
    printf("希尔排序之后的数据\n");
    //ShellSort(arr,10);
    ShellSort2(arr, 10);
    Print(arr, 10);
}

void main(){
    Test();
    system("pause");
}

时间: 2024-10-19 11:46:25

数据结构 排序(希尔排序)的相关文章

排序算法3--插入排序--希尔排序(缩小增量排序)

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

排序——希尔排序

希尔排序(Shell Sort)是插入排序的一种.是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组.所有距离为d1的倍数的记录放在同一个组中.先在各组内进行直接插入排序:然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<-<d2<d1),即所有记录放在同一组中进行直接插入排序为止. 希尔排序的实现代码: #inclu

数据结构排序-希尔排序

希尔排序也是插入排序的一种,但是它效率高于直接插入排序. 基本思想是: 首先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组.所有距离为d1的倍数的记录放在同一个组中.先在各组内进行直接插入排序: 然后,取第二个增量d2<的重复上述的分组和排序,直到所取的增量dt=1. 增量序列尤其关键,一般的初次取序列的一半为增量,以后每次减半,直到增量为1. 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int n; 5 6 /*

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

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.希尔排序是非稳定排序算法. 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位 原始的算法实现在最坏的情况下需要进行O(n2)的比较和交换.V. Pratt的书对算法进行了少量修改,可以使得性能提升至O(nlog2n).这比最好的比较算法的O(nlogn)要差一些. 希尔排序通过将比较

数据结构_希尔排序(分组加直接插入排序)

希尔排序介绍 希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 希尔排序实质上是一种分组插入方法.它的基本思想是:对于n个待排序的数列,取一个小于n的整数gap(gap被称为步长)将待排序元素分成若干个组子序列,所有距离为gap的倍数的记录放在同一个组中:然后,对各组内的元素进行直接插入排序. 这一趟排序完成之后,每一个组的元素都是有序的.然后减小gap的值,并重复执行上述的分组和排序.重复这样的

数据结构(七)排序---希尔排序

图解排序算法(二)之希尔排序 定义 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 基本有序:小的关键字基本在前面,大的基本在后面,不大不小的基本在中间 基本思想 简单

Java数据结构之排序---希尔排序

希尔排序的基本介绍: 希尔排序同之前的插入排序一样,它也是一种插入排序,只不过它是简单插入排序之后的一个优化的排序算法,希尔排序也被称为缩小增量排序. 希尔排序的基本思想: 希尔排序是把数组中给定的元素按照下标的一定增量进行分组,在分组之后,对每组使用直接插入排序算法:随着增量的减少,每组包含的元素越来越多,当增量减少到1的时候,整个数组正好被分成一组,此时该算法终止.通常我们判断增量是通过:第一次的增量=数组的长度/2(取整),第二次的增量=第一次的增量/2(取整)...一直到增量为1结束.

排序——希尔排序算法实现

最近在和师兄探讨希尔排序的实现原理,得到了师兄的点拨. 进入正题,讲希尔排序首先就要将插入排序,插入排序的原理很简单:给定数组a的[ first,last)区间,经过 i-1次排序之后,a[first]...a[first+i-1]已排好序.第 i  遍处理就是将 a[first+i]插入到a[first]...a[first+i-1]中合适的位置.,是的啊a[first]...a[first+i]成为一个排好序的序列.     可以利用顺序比较的方法来实现. 由于插入排序很简单,所以就不BB了

python排序-希尔排序

Shell 排序利用分组加速部分有序数组排序,分组定长跳跃冒泡 希尔排序的时间性能优于直接插入排序的原因: ①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少. ②当n值较小时,n和 n^2 的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0( )差别不大. ③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的

js排序 希尔排序,快速排序

希尔排序: 定义一个间隔序列,例如是5,3,1.第一次处理,会处理所有间隔为5的,下一次会处理间隔为3的,最后一次处理间隔为1的元素.也就是相邻元素执行标准插入排序. 在开始最后一次处理时,大部分元素都将在正确的位置,算法就不必对很多元素进行交换,这是比插入元素高级的地方. 时间复杂度O(n*logn) 1 function shellSort(){ 2 var N=arr.length; 3 var h=1; 4 while(h<N/3){ 5 h=3*h+1;//设置间隔 6 } 7 whi