【数据结构实验】排序(二)希尔排序算法的详细介绍与性能分析

news2024/11/18 4:47:59

文章目录

  • 1. 引言
  • 2. 希尔排序算法原理
    • 2.1 示例说明
    • 2.2 时间复杂性分析
  • 3. 实验内容
    • 3.1 实验题目
      • (一)输入要求
      • (二)输出要求
    • 3.2 算法实现
    • 3.3 代码解析
    • 3.4 实验结果
  • 4. 实验结论

1. 引言

  排序算法在计算机科学中扮演着至关重要的角色,对于数据的组织和搜索等任务有着深远的影响。希尔排序是一种插入排序的改进版本,通过引入增量的概念,能够在某些情况下显著提高排序的效率。

  本文将详细介绍希尔排序算法的原理、实现,以及对其性能进行分析。

2. 希尔排序算法原理

  希尔排序是一种基于插入排序的改进算法,由Donald L. Shell于1959年提出。其核心思想是将待排序的记录按下标的一定增量分组,对每组使用直接插入排序方法,随着增量逐渐减小,每组包含的记录越来越多,直至增量为1时,整个序列恰好被分成一个组,排序完成。

2.1 示例说明

  考虑一个包含16个记录的输入文件,取渐减增量序列为 8 , 4 , 2 , 1 8, 4, 2, 1 8,4,2,1。初始时,将输入文件分成8个组:

  • 组1: R 1 , R 9 R_1, R_9 R1,R9
  • 组2: R 2 , R 10 R_2, R_{10} R2,R10
  • 组3: R 3 , R 11 R_3, R_{11} R3,R11
  • 组8: R 8 , R 16 R_8, R_{16} R8,R16

  对每个组使用直接插入排序算法进行排序。然后,取增量值为4,将文件分成4个组:

  • 组1: R 1 , R 5 , R 9 , R 13 R_1, R_5, R_9, R_{13} R1,R5,R9,R13
  • 组2: R 2 , R 6 , R 10 , R 14 R_2, R_6, R_{10}, R_{14} R2,R6,R10,R14
  • 组3: R 3 , R 7 , R 11 , R 15 R_3, R_7, R_{11}, R_{15} R3,R7,R11,R15
  • 组4: R 4 , R 8 , R 12 , R 16 R_4, R_8, R_{12}, R_{16} R4,R8,R12,R16

  再次对每个组使用直接插入排序。重复这个过程,取增量值为2和1,最终完成整个排序。
在这里插入图片描述

2.2 时间复杂性分析

  希尔排序的性能与所选取的分组长度序列密切相关。最坏情况下的时间复杂度为 O ( n 2 ) O(n^2) O(n2),但不同的分组长度序列会影响算法的实际性能。

  • 当分组长度序列取 n 2 i \frac{n}{2^i} 2in时,最坏情况下时间复杂度为 O ( n 2 ) O(n^2) O(n2)
  • 实际应用中,取2.2作为递减因子效果更好。
  • 当分组长度序列取形如 2 p 3 q 2^p3^q 2p3q且小于n的所有正整数的集合时,希尔排序的时间复杂度为 O ( n ⋅ ( log ⁡ 2 n ) 2 ) O(n \cdot (\log_2 n)^2) O(n(log2n)2)

  1969年,V. Pratt证明了以上结论。目前已知的最好分组长度序列是 { 1 , 4 , 10 , 23 , 57 , 132 , 301 , 701 , 1750 , . . . } \{1, 4, 10, 23, 57, 132, 301, 701, 1750, ... \} {1,4,10,23,57,132,301,701,1750,...},具有此分组序列的希尔排序比插入排序和堆排序要快。在小数组情况下比快速排序快,但对于大数组则可能比快速排序慢。此外,希尔排序是不稳定的排序算法

3. 实验内容

3.1 实验题目

以{7,5,3,1}为渐减增量序列实现希尔排序算法 ShellSort.

(一)输入要求

第一组输入数据:
{27,32,33,21,57,96,64,87,14,43,15,62,99,11}
第二组输入数据:
{11,14,15,21,27,32,33,43,57,62,64,87,96,99}
第三组输入数据:
{99,96,87,64,62,57,43,33,32,27,21,15,14,11}

(二)输出要求

对每组输入数据,输出以下信息(要求必须要有关于输出数据的明确的提示信息):

  1. 输出整个排序过程总的关键词比较次数和总的记录移动次数;
  2. 每发生一次记录插入,输出整个文件一次;
  3. 输出增量为 7、5、3、1 时的关键词比较次数和记录移动次数

3.2 算法实现

#include <stdio.h>
#define n 14
void ShellSort(int R[n]){
    int r,i,j,k,Compare=0,Move=0;
    int d=7;	//初始化增量值为7
    while(d>0){		//不断分组,并对各组排序
   		int compare=0,move=0;
        for(i=d;i<n;i++){	//对各组做直接插入排序
            r=R[i];
            j=i;
            while(j>d-1&&R[j-d]>r){
            	compare++;
                R[j]=R[j-d];
                j-=d;
            }
            if(j!=i){
            	move++;
            	R[j]=r;
            	for(k=0;k<n;k++){
           	 	    printf("%d ", R[k]);
            	}
            	printf("\n");
			}  
        }
        printf("\n增量值为%d时的关键词比较次数是%d,记录移动次数是%d\n\n",d,compare,move);
        d=d-2; 	//计算新的增量值,{7,5,3,1}
   		Compare+=compare;
		Move+=move;
    }
    printf("关键词的总比较次数是%d,总的记录移动次数是%d\n",Compare,Move);
}
int main(){
    int i;
    //int R[n]={27,32,33,21,57,96,64,87,14,43,15,62,99,11};
    int R[n]={11,14,15,21,27,32,33,43,57,62,64,87,96,99};
    //int R[n]={99,96,87,64,62,57,43,33,32,27,21,15,14,11};
    ShellSort(R);
    printf("最后结果:");
    for(i=0;i<n;i++){
        printf("%d ",R[i]);
    }
}

3.3 代码解析

  • 宏定义
#define n 14

  定义宏 n,表示数组的长度为14,在后续代码中可以方便地使用 n 来表示数组的长度,而不需要硬编码。

  • 希尔排序函数
      参数是一个整型数组 R,表示待排序的数组。在函数内部,通过不断缩小增量的方式,对数据进行插入排序。具体来说,在每一轮循环结束后,更新增量的值,采用一定的方式递减。这里选择减小2的增量序列 {7, 5, 3, 1}

    int d = 7;
    while (d > 0) {
    	// ...
    	d=d-2; 	//计算新的增量值,{7,5,3,1}
    	// ...
    }
    

      使用 while 循环,不断缩小增量 d,并在每一轮循环中进行插入排序。增量的选择是关键,这里初始设置为7,然后逐渐减小。

    for (i = d; i < n; i++) {
    // ...
    }
    

    针对每个分组,从第 d 个元素开始,进行插入排序。

    while (j > d - 1 && R[j - d] > r) {
    // ...
    }
    

    在插入排序的过程中,通过比较和移动元素,确保分组内的元素是有序的。

  • 输出结果

printf("\n增量值为%d时的关键词比较次数是%d,记录移动次数是%d\n\n", d, compare, move);

  在每一轮排序结束后,输出该轮排序的比较次数和记录移动次数,从而了解算法在不同步长下的性能。

printf("关键词的总比较次数是%d,总的记录移动次数是%d\n", Compare, Move);

  在整个排序完成后,输出总的比较次数和记录移动次数,提供了算法整体性能的信息。

  • 主函数
int main(){
    int i;
    // int R[n]={27,32,33,21,57,96,64,87,14,43,15,62,99,11};
    // int R[n]={11,14,15,21,27,32,33,43,57,62,64,87,96,99};
    int R[n]={99,96,87,64,62,57,43,33,32,27,21,15,14,11};
    ShellSort(R);
    printf("最后结果:");
    for(i=0;i<n;i++){
        printf("%d ",R[i]);
    }
}

  创建一个包含14个元素的数组 R,并调用 ShellSort 函数对其进行排序。最后输出排序后的数组。

3.4 实验结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 实验结论

  希尔排序是一种高效的排序算法,通过引入增量的方式,能够在某些情况下显著提高插入排序的性能。选择合适的分组长度序列对算法的实际效果有重要影响,而已知的最佳序列 { 1 , 4 , 10 , 23 , 57 , 132 , 301 , 701 , 1750 , . . . } \{1, 4, 10, 23, 57, 132, 301, 701, 1750, ... \} {1,4,10,23,57,132,301,701,1750,...}在实践中表现优异。

  需要注意的是,希尔排序是不稳定的排序算法。在实际应用中,根据数据规模和特性选择不同的排序算法是很重要的,希尔排序在一些场景下可能比其他排序算法更适用。希尔排序的性能对于分组长度序列的选择非常敏感,因此在实际使用中需要根据具体情况进行调优。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1252680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

坚鹏:中国银联公司银行业前沿技术介绍及其数据分析方法实战培训

中国银联公司银行业前沿技术介绍及其数据分析方法实战培训圆满结束 ——借力数字化技术实现基于场景的精准化、场景化、智能化营销 中国银联公司&#xff08;China UnionPay&#xff09;成立于2002年3月&#xff0c;是经国务院同意&#xff0c;中国人民银行批准&#xff0c;在合…

一种太阳能风能市电互补路灯方案介绍

太阳能市电互补路灯是一种环保、节能的照明设施&#xff0c;它利用太阳能进行发电并实现照明。这种路灯在白天吸收阳光并将其转化为电能&#xff0c;到了晚上则利用储存的电能为LED灯提供电力&#xff0c;实现照明功能。下面叁仟智慧将详细介绍太阳能市电互补路灯灯的工作原理和…

人工智能|机器学习——循环神经网络的简洁实现

循环神经网络的简洁实现 如何使用深度学习框架的高级API提供的函数更有效地实现相同的语言模型。 我们仍然从读取时光机器数据集开始。 import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 t…

4-20mA高精度采集方案

下载链接&#xff01;https://mp.weixin.qq.com/s?__bizMzU2OTc4ODA4OA&mid2247557466&idx1&snb5a323285c2629a41d2a896764db27eb&chksmfcfaf28dcb8d7b9bb6211030d9bda53db63ab51f765b4165d9fa630e54301f0406efdabff0fb&token976581939&langzh_CN#rd …

明道云伙伴成果与展望

摘要&#xff1a;这篇文章介绍了明道云在过去一年的成果以及未来的计划。明道云将把更多资源和精力投入到伙伴身上&#xff0c;提供更全面的支持&#xff0c;包括产品特性、展业支持和 GTM &#xff08;Go-To-Market&#xff09;支持三个方面。在产品特性方面&#xff0c;明道云…

【数据结构实验】排序(一)冒泡排序改进算法 Bubble及其性能分析

文章目录 1. 引言2. 冒泡排序算法原理2.1 传统冒泡排序2.2 改进的冒泡排序 3. 实验内容3.1 实验题目&#xff08;一&#xff09;输入要求&#xff08;二&#xff09;输出要求 3.2 算法实现 4. 实验结果5. 实验结论 1. 引言 排序算法是计算机科学中一个重要而基础的研究领域&…

03:2440--UART

目录 一:UART 1:概念 2:工作模式 3:逻辑电平 4:串口结构图 5:时间的计算 二:寄存器 1:简单的UART传输数据 A:GPHCON--配置引脚 B:GPHUP----使能内部上拉​编辑 C: UCON0---设置频率115200 D: ULCON0----数据格式8n1 E:发送数据 A:UTRSTAT0 B:UTXHO--发送数据输…

makefile 学习(5)完整的makefile模板

参考自&#xff1a; (1&#xff09;深度学习部署笔记(二): g, makefile语法&#xff0c;makefile自己的CUDA编程模板(2&#xff09;https://zhuanlan.zhihu.com/p/396448133(3) 一个挺好的工程模板&#xff0c;(https://github.com/shouxieai/cpp-proj-template) 1. c 编译流…

linux嵌入式时区问题

目录 操作说明实验参考 最近有个针对时区的需求&#xff0c;研究了下。 查询网上的一些设置&#xff0c;发现基本都是系统中自带的一些文件&#xff0c;然后开机时解析&#xff0c;或者是有个修改的命令。 操作 但针对嵌入式常用到的 busybox 制作的最小系统&#xff0c;并没…

图论|知识图谱——详解自下而上构建知识图谱全过程

导读&#xff1a;知识图谱的构建技术主要有自顶向下和自底向上两种。其中自顶向下构建是指借助百科类网站等结构化数据源&#xff0c;从高质量数据中提取本体和模式信息&#xff0c;加入到知识库里。而自底向上构建&#xff0c;则是借助一定的技术手段&#xff0c;从公开采集的…

activiti流程回退与跳转

学习连接 【工作流Activiti7】3、Activiti7 回退与会签 【工作流Activiti7】4、Activiti7 结束/终止流程 Activiti-跳转到指定节点、回退 ativiti6.0 流程节点自由跳转实现、拒绝/不同意/返回上一节点、流程撤回、跳转、回退等操作&#xff08;通用实现&#xff0c;亲测可用…

基于python+TensorFlow+Django算法模型的车辆车型识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介简介技术栈主要模块1. 数据预处理2. 模型构建3. 模型训练4. 模型集成5. 用户界面 系统工作流程未来改进计划 二、功能三、系统四. 总结 一项目简介 # 车辆车…

【linux】基本指令(中篇)

echo指令 将引号内容打印到显示屏上 输出的重定向 追加的重定向 输出的重定向 我们学习c语言的时候当以写的方式创建一个文件&#xff0c;就会覆盖掉该文件之前的内容 当我们以追加的方式打开文件的时候&#xff0c;原文件内容不会被覆盖而是追加 more指令 10.more指令…

cephadm部署ceph quincy版本

环境说明 IP主机名角色 存储设备 192.168.2.100 master100 mon,mgr,osd,mds,rgw 大于5G的空设备192.168.2.101node101mon,mgr,osd,mds,rgw大于5G的空设备192.168.2.102node102mon,mgr,osd,mds,rgw大于5G的空设备 关闭防火墙 关闭并且禁用selinux 配置主机名/etc/hosts …

⑦【Redis GEO 】Redis常用数据类型:GEO [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Redis GEO ⑦Redis GEO 基本操作命令1.geoadd …

原生JS实现计算器(内含源码)

前言 本文讲解了JavaScript如何在一小时内实现一个简易计算器&#xff0c;这里最大的亮点就在于&#xff0c;我在JS中只用了一个事件&#xff0c;就实现了计算器的效果和功能&#xff0c;那么好文本正式开始。 布局和样式流程 首先是HTMLCSS结构&#xff1a;这里主要用到的…

基于uQRCode封装的Vue3二维码生成插件

标题&#xff1a;基于uQRCode封装的Vue3二维码生成插件 摘要&#xff1a;本文介绍了一种基于uQRCode封装的Vue3二维码生成插件&#xff0c;可以在Javascript运行环境下生成二维码并返回图片地址。该插件适用于所有Javascript运行环境&#xff0c;并且支持微信小程序。本文将详…

在Python中matplotlib函数的plt.plot()函数的颜色参数设置,以及可以直接运行的程序代码!

文章目录 前言一、使用字符串颜色&#xff1a;二、使用十六进制颜色&#xff1a;三、使用RGB元组&#xff1a;四、使用颜色映射&#xff1a;总结 前言 在matplotlib中&#xff0c;plt.plot()函数可以接受颜色参数&#xff0c;可以设置为字符串颜色&#xff08;如red&#xff0…

笔记:pycharm当有多个plt.show()时候,只显示第一个plt.show()

import matplotlib.pyplot as plt import numpy as np# 创建数据 x np.linspace(0, 10, 100) y1 np.sin(x) y2 np.cos(x) y3 np.tan(x) y4 np.exp(x)# 创建一个2x2的子图网格 # fig plt.figure() fig,((ax1, ax2), (ax3, ax4)) plt.subplots(nrows2, ncols2, figsize(8,…

Redis:事务操作

目录 Redis事务定义相关命令事务的错误处事务冲突的问题Redis事务三特性 Redis事务定义 redis事务是一个单独的隔离操作&#xff0c;事务中的所有命令都会序列化、按顺序地执行&#xff0c;事务在执行的过程中&#xff0c;不会被其他客户端发送来的命令请求所打断。 redis事务…