当前位置: 首页 > news >正文

排序算法总结(三)希尔排序

访问www.tomcoding.com网站,学习Oracle内部数据结构,详细文档说明,下载Oracle的exp/imp,DUL,logminer,ASM工具的源代码,学习高技术含量的内容。

如果你在网上搜一下希尔排序,都会告诉你希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。然后列一些图标或动画演示,最后给出一个算法函数。你看了以后还是不知道什么是希尔排序,里面的图太复杂,你看上好几遍也不能抓住重点。

我们来看一下希尔排序算法要解决的问题,都说希尔算法是插入排序的改进版,那么为什么要改进呢?原因是插入排序要进行大量的元素交换(位置移动),在完全升序排列的数组中,算法最高效,不需要进行交换,在完全降序的数组中,算法效率最低。为了改善这种情况,希尔排序把数组中的元素先进行多个分组,然后把每个分组按照插入排序算法升序排列,然后减少分组的个数,再进行插入排序,最后预排序的数组不再分组,进行最后一次插入排序。预排序的目的就是把数组中数值小的元素尽量放到数组前面,减少最后一次排序元素交换的次数。

那么怎样分组呢?最容易想到的就是第一次分组使得两个元素一组,那么如果有n个元素,就有n/2个分组,如果n不能被2整除,那么留下一个元素不分组。第二次分组把第一次分组的个数再减半,依次类推,直到再减半就是0了,说明是最后一次分组了,那么把最后一次分组进行一次插入排序,数组中的元素就按升序排列好了。这里数组元素个数为单数时,最后一个元素不参与分组排序,直到最后一次插入排序时才参与。

看一下程序。

static void shell_sort(int *ai, int n)

{

    int         i, j;

    int         gap, ne;

    int         *t;

    /* gap是间隙,表示每隔gap值的元素分为一组

     * ne是每一组中包含多少个元素

     * 在这里先分配跟原数组大小一样的数组,用于分组

     */

    if ((t = (int *)malloc(n*sizeof(int))) == NULL)

        return;

    /* 起始gap取元素个数的半数值,这样每一组只包含两个元素

     * gap每次循环后减半,直到为1,退出循环,进行最后一次插入排序

     */

    for (gap = n/2, ne = n/gap; gap > 1; gap /= 2, ne = n/gap) {

        /* 把原数组ai中的元素分组,分完组后进行插入排序 */

        for (i = 0; i < gap; i++) {

            /* 下面的循环完成后,生成了一个分组 */

            for (j = 0; j < ne; j++)

                t[i*ne+j] = ai[i+j*gap];

            /* 对刚生成的分组排序 */

            insertion_sort(&t[i*ne], ne);

        }

        /* 每一次分组排序结束后,把排序后的元素恢复到原来数组的位置上 */

        for (i = 0; i < gap; i++) {

            for (j = 0; j < ne; j++)

                ai[i+j*gap] = t[i*ne+j];

        }

    }

    /* gap=1,进行最后一次排序,这时如果元素个数是单数,最后一个元素也会参与排序 */

    insertion_sort(ai, n);

    /* 释放掉分配的内存 */

    free(t);

}

上面实现的这个排序算法,看起来臃肿,还需要辅助的数组,但直观的表现了希尔算法是分组插入排序算法的本质。

其实每个组都是相同间隔的元素组成的,还是在同一个数组中,这样把插入排序算法揉进分组里去,就能简化代码,看一下整合后的函数。

void shell_sort(int *ai, int n) {

    int     i, j;

    int     gap, t;

    for(gap = n/2; gap > 0; gap /= 2) {

        for(i = gap; i < n; i++) {

            for(j = i - gap; j >= 0 && ai[j] > ai[j+gap]; j -= gap) {

                /* 交换元素位置 */

                t         = ai[j];

                ai[j]     = ai[j+gap];

                ai[j+gap] = t;

            }

        }

    }

}

相关文章:

排序算法总结(三)希尔排序

访问www.tomcoding.com网站&#xff0c;学习Oracle内部数据结构&#xff0c;详细文档说明&#xff0c;下载Oracle的exp/imp&#xff0c;DUL&#xff0c;logminer&#xff0c;ASM工具的源代码&#xff0c;学习高技术含量的内容。 如果你在网上搜一下希尔排序&#xff0c;都会告…...

如何迁移 Linux 服务器 第一部分 - 系统准备

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 在许多情况下&#xff0c;您可能需要将数据和操作需求从一个服务器迁移到另一个服务器。您可能需要在新的数据中心实施解决方案&a…...

网络IO模型都有哪些

“网络IO模型有BIO、NIO、AIO ” “他们分别代表什么&#xff0c;有什么区别吗&#xff1f; BIO&#xff1a;同步阻塞IO。 NIO&#xff1a;同步非阻塞IO。 AIO&#xff1a;异步非阻塞IO。 “BIO为什么是同步阻塞IO&#xff0c;他阻塞的是谁跟谁之间的关联&#xff1f;”。 首先…...

数据结构: 数组在算法中的应用

数组是计算机科学中的一种基础数据结构&#xff0c;它在算法中有着广泛的应用&#xff0c;其关键要素是索引与索引对应的值。 请注意&#xff0c;这些代码示例需要适当的辅助函数&#xff08;如 swap &#xff09;和主函数来运行。此外&#xff0c;一些算法&#xff08;如KMP算…...

js快速转换时间(时间戳转换成年月日时分秒)

1&#xff1a;js转换 1728270833000 转换为 2024-10-07 11:13:53 var date new Date(1728270833000); // 参数需要毫秒数&#xff0c;所以这里将秒数乘于 1000 Y date.getFullYear() -; M (date.getMonth()1 < 10 ? 0(date.getMonth()1) : date.getMonth()1) -; D…...

LeetCode15.三数之和

题目链接&#xff1a;15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 1.常规解法&#xff08;会超时&#xff09; 由于这道题需要排除相同的三元组&#xff0c;则可以先将目标数组从小到大排序&#xff0c;再遍历数组找到每个符合条件的三元组&#xff0c;若结果中不包…...

SpringBoot3.3 优雅启停定时任务

定时任务是非常常见的功能,在一个复杂的应用程序中,如何优雅地管理这些定时任务的启动与停止尤为重要。 Spring Boot 提供了强大的任务调度支持,通过@Scheduled注解可以轻松地创建定时任务,并且可以通过配置来灵活地管理这些任务的执行环境。在本文中,我们将深入探讨如何…...

数据结构之二叉搜索树(key模型与key_value模型)

二叉搜索树&#xff08;key模型与key_value模型&#xff09; 1. ⼆叉搜索树的概念2. ⼆叉搜索树的性能分析3. ⼆叉搜索树的插⼊4. ⼆叉搜索树的查找5. ⼆叉搜索树的删除6. ⼆叉搜索树的实现代码7. ⼆叉搜索树key和key/value使⽤场景7.1 key搜索场景&#xff1a;7.2 key/value搜…...

图说几何学2300年重大错误:附着在直线z上的直线段必是z的一部分

黄小宁 用泡沫塑料和油漆制成的铅球与真正的铅球&#xff0c;两者有不同的内部形状。同样&#xff0c;数学有长度相同但内部形状不同的伪≌直线段。 几何学有史2300年来一直认定附着在直线z上的直线段一定是z的一部分。其实这是2300年肉眼直观错觉——百年病态集论的症结。 …...

汽车网关(GW)技术分析

一、引言 在现代汽车电子系统中&#xff0c;汽车网关&#xff08;Gateway&#xff0c;简称 GW&#xff09;扮演着至关重要的角色。随着汽车电子技术的不断发展&#xff0c;汽车内部的电子控制单元&#xff08;Electronic Control Unit&#xff0c;简称 ECU&#xff09;数量不断…...

Telnet命令详解:安装、用法及应用场景解析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…...

C++之LIST模拟实现(代码纯享版)

目录 文章目录 前言 一、代码 总结 前言 本文主要展示了模拟List的代码实现 一、代码 #pragma once #include<iostream> #include<assert.h> using namespace std; namespace zlh {template<class T>struct list_node{T _data;list_node<T>* _next;l…...

华为OD机试 - 括号匹配 - 栈(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…...

打破欧美10年芯片垄断,杨振宁教授关门弟子,仅用三年创造奇迹

有这么一位超级厉害的中国人&#xff0c;硬是把欧美那边垄断了十年的芯片技术给“撬”开了&#xff01;说起来&#xff0c;这才是我们该追的真正明星啊&#xff01;那么&#xff0c;这位大神到底是谁&#xff1f;又是怎么让欧美芯片圈儿里的人听到她的名字就心里发怵的呢&#…...

OpenCV视频I/O(20)视频写入类VideoWriter之用于将图像帧写入视频文件函数write()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::VideoWriter::write() 函数用于将图像帧写入视频文件。 该函数/方法将指定的图像写入视频文件。图像的大小必须与打开视频编写器时指定的大…...

音视频入门基础:FLV专题(14)——FFmpeg源码中,解码Script Tag的实现

一、引言 在《音视频入门基础&#xff1a;FLV专题&#xff08;9&#xff09;——Script Tag简介》中对Script Tag进行了简介&#xff0c;本文讲述FFmpeg源码中是怎样解码FLV文件的Script Tag&#xff0c;拿到里面的信息。 二、flv_read_packet函数 从《音视频入门基础&#x…...

小猿口算APP脚本(协议版)

小猿口算是一款专注于数学学习的教育应用,主要面向小学阶段的学生。它提供多种数学练习和测试,包括口算、速算、应用题等。通过智能化的题目生成和实时批改功能,帮助学生提高数学计算能力。此外,它还提供详细的学习报告和分析,帮助家长和教师了解学生的学习进度和薄弱环节…...

【长文梳理webserver核心】核心类篇

前言 有三个核心组件支撑一个reactor实现 [持续] 的 [监听] 一组fd&#xff0c;并根据每个fd上发生的事件 [调用] 相应的处理函数。这三个组件就是 EventLoop 、Channel 以及 Poller 三个类&#xff0c;其中 EventLoop 可以看作是对业务线程的封装&#xff0c;而 Channel 可以看…...

[实用工具]Docker安装nextcloud实现私有云服务和onlyoffice

Nextcloud是一款开源的云存储和协作平台&#xff0c;允许用户在自己的服务器上存储和访问文件&#xff0c;同时提供强大的协作工具。它可以替代商业云存储服务&#xff0c;让用户拥有完全控制和自主管理自己的数据。 Nextcloud支持文件上传和下载&#xff0c;可以通过Web界面、…...

基于STM32设计的生猪健康检测管理系统(NBIOT+OneNet)(240)

文章目录 一、前言1.1 项目介绍【1】项目开发背景【2】设计实现的功能【3】项目硬件模块组成1.2 设计思路1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】项目背景【5】摘要1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 系统功能总结1.6 系统框架图…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...