【希尔排序算法】详解:原理、实现与优化

【希尔排序算法】详解:原理、实现与优化

【希尔排序算法】详解:原理、实现与优化

🌺The Begin🌺点点关注,收藏不迷路🌺

一、算法概述

希尔排序(Shell Sort)是Donald Shell于1959年提出的一种改进的插入排序算法,又称缩小增量排序。它通过将原始数组分解为若干个子序列进行插入排序,随着增量逐渐减小,最终对整个数组进行一次插入排序。

基本特性

  • 时间复杂度:取决于增量序列,通常为O(n^(1.3-2))
  • 空间复杂度:O(1)(原地排序)
  • 稳定性:不稳定排序算法
  • 适用场景:中等规模数据,特别是部分有序的数据

二、算法原理详解

核心思想

  1. 分组插入排序:按照增量gap将数组分为若干子序列
  2. 逐步缩小增量:每次缩小gap值,直到gap=1
  3. 最终插入排序:当gap=1时,就是标准的插入排序

增量序列选择

常用的增量序列:

  • Shell原始序列:gap = n/2, n/4, …, 1
  • Hibbard序列:1, 3, 7, …, 2^k-1
  • Sedgewick序列:1, 5, 19, 41, 109,…

三、算法流程图示

示例数组:[8, 9, 1, 7, 2, 3, 5, 4, 6, 0]

初始状态
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ 8 │ 9 │ 1 │ 7 │ 2 │ 3 │ 5 │ 4 │ 6 │ 0 │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 
第一轮:gap=5

将数组分为5组:(8,3), (9,5), (1,4), (7,6), (2,0)

分组示意图: ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ 8 │ │ │ │ │ 3 │ │ │ │ │ → (8,3) │ │ 9 │ │ │ │ │ 5 │ │ │ │ → (9,5) │ │ │ 1 │ │ │ │ │ 4 │ │ │ → (1,4) │ │ │ │ 7 │ │ │ │ │ 6 │ │ → (7,6) │ │ │ │ │ 2 │ │ │ │ │ 0 │ → (2,0) └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 排序后结果: ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ 3 │ 5 │ 1 │ 6 │ 0 │ 8 │ 9 │ 4 │ 7 │ 2 │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 
第二轮:gap=2

将数组分为2组:
(3,1,0,9,7), (5,6,8,4,2)

分组示意图: ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ 3 │ │ 1 │ │ 0 │ │ 9 │ │ 7 │ │ → (3,1,0,9,7) │ │ 5 │ │ 6 │ │ 8 │ │ 4 │ │ 2 │ → (5,6,8,4,2) └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 排序后结果: ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ 0 │ 2 │ 1 │ 4 │ 3 │ 5 │ 7 │ 6 │ 9 │ 8 │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 
第三轮:gap=1(标准插入排序)
最终排序结果: ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘ 

四、完整Java实现

packagecom.kwan.springbootkwan.controller;publicclassShellSort{/** * 基础希尔排序(使用Shell原始增量序列) * @param arr 待排序数组 */publicstaticvoidshellSort(int[] arr){if(arr ==null|| arr.length <=1){return;}int n = arr.length;// 初始gap为数组长度的一半,逐步缩小gap直到1for(int gap = n /2; gap >0; gap /=2){// 从第gap个元素开始,对各个子序列进行插入排序for(int i = gap; i < n; i++){int temp = arr[i];int j;// 对子序列进行插入排序for(j = i; j >= gap && arr[j - gap]> temp; j -= gap){ arr[j]= arr[j - gap];} arr[j]= temp;}}}// 测试代码publicstaticvoidmain(String[] args){int[] arr ={8,9,1,7,2,3,5,4,6,0};System.out.println("原始数组:");printArray(arr);System.out.println("\n希尔排序后:");shellSort(arr);printArray(arr);}// 打印数组privatestaticvoidprintArray(int[] arr){for(int num : arr){System.out.print(num +" ");}System.out.println();}}
在这里插入图片描述

五、算法分析

时间复杂度分析

希尔排序的时间复杂度取决于增量序列的选择

增量序列最坏时间复杂度平均时间复杂度
Shell原始序列O(n²)O(n^(1.5))
Hibbard序列O(n^(3/2))O(n^(5/4))
Sedgewick序列O(n^(4/3))O(n^(7/6))

空间复杂度

  • 只需要常数级别的额外空间
  • 空间复杂度:O(1)

稳定性

希尔排序是不稳定的排序算法,因为相同的元素可能会被分到不同的子序列中,导致相对顺序改变。

六、实际应用场景

  1. 中等规模数据排序:当数据量在几千到几万时,希尔排序表现良好
  2. 嵌入式系统:由于空间复杂度低,适合资源受限的环境
  3. 作为更复杂算法的预处理步骤:可以先使用希尔排序进行部分排序

七、与其他排序算法的对比

算法平均时间复杂度最坏时间复杂度空间复杂度稳定性
希尔排序O(n^(1.3-2))O(n²)O(1)不稳定
插入排序O(n²)O(n²)O(1)稳定
快速排序O(nlogn)O(n²)O(logn)不稳定
归并排序O(nlogn)O(nlogn)O(n)稳定

八、总结

希尔排序通过分组插入排序的思想,有效减少了数据移动的次数,是对简单插入排序的重要改进。虽然其时间复杂度理论分析较为复杂,但在实际应用中,特别是中等规模数据的排序场景下,希尔排序往往能提供不错的性能表现。

选择合适的增量序列对希尔排序的性能至关重要,Hibbard序列和Sedgewick序列在实践中表现良好。希尔排序的实现简单,空间效率高,是值得掌握的经典排序算法之一。

在这里插入图片描述

🌺The End🌺点点关注,收藏不迷路🌺

Read more

llama.cpp量化模型部署实战:从模型转换到API服务

1. 为什么你需要关注llama.cpp:让大模型在普通电脑上跑起来 如果你对AI大模型感兴趣,肯定听说过动辄需要几十GB显存的“庞然大物”。想在自己的电脑上跑一个7B参数的模型,以前可能得配一张昂贵的专业显卡。但现在,情况不一样了。我今天要跟你聊的 llama.cpp,就是那个能让大模型“瘦身”并飞入寻常百姓家的神奇工具。 简单来说,llama.cpp是一个用C/C++编写的开源项目,它的核心目标只有一个:用最高效的方式,在消费级硬件(比如你的笔记本电脑CPU)上运行大型语言模型。它不像PyTorch那样是个庞大的深度学习框架,它更像一个“推理引擎”,专注于把训练好的模型,以最小的资源消耗跑起来。 我刚开始接触大模型部署时,也被各种复杂的依赖和巨大的资源需求劝退过。直到用了llama.cpp,我才发现,原来在我的MacBook Pro上,也能流畅地和Llama 2这样的模型对话。这背后的功臣,主要就是两点:纯C/C++实现带来的极致性能,以及模型量化技术带来的体积与速度革命。量化这个词听起来有点技术,你可以把它想象成给模型“压缩图片”

By Ne0inhk

你的连接不是专用连接攻击者可能试图从 github.com 窃取你的信息(例如,密码、消息或信用卡)。 --解决办法

我遇到了. 检查安全软件或企业防火墙/代理 (包括 VPN)这个问题,关了就好,我是用来xbox加速github,所以先开在关既可以加速又可以访问 这个错误表明你的浏览器(Microsoft Edge)无法安全地连接到 GitHub,因为遇到了证书验证问题(NET::ERR_CERT_AUTHORITY_INVALID)。错误信息明确指出网站使用了 HSTS(HTTP Strict Transport Security),这会强制浏览器只使用 HTTPS 连接,并且阻止你忽略证书错误(即使你尝试点击“高级”然后“继续访问”也是无效的)。 问题核心原因: 你的浏览器不信任 GitHub 网站当前提供的 SSL/TLS 证书的颁发机构(Certificate Authority, CA)。这通常不是 GitHub 自身的问题(他们的证书通常是有效的),而是你的本地环境或连接出了问题。

By Ne0inhk
Git 分支管理完全指南:从基础到团队协作

Git 分支管理完全指南:从基础到团队协作

🔥个人主页:Cx330🌸 ❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》 《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔 《Git深度解析》:版本管理实战全解 🌟心向往之行必能至 🎥Cx330🌸的简介: 目录 前言: 一、为什么要分支?——分支的意义 二. Git 分支基础:核心概念与常用命令 2.1 分支与 HEAD 指针解析 2.2 基础指令:查看、创建、切换分支 三. Git 分支进阶:合并、删除和冲突 3.1 合并分支(git merge 分支名) 3.2 删除分支(

By Ne0inhk
Windows环境Git安装教程(下载Git安装包、安装Git、验证Git是否安装成功、设置名字和邮箱)

Windows环境Git安装教程(下载Git安装包、安装Git、验证Git是否安装成功、设置名字和邮箱)

文章目录 * 1. 下载Git安装包 * 1.1 通过清华大学开源软件镜像站下载(推荐) * 1.2 通过Git官网下载 * 1.3 通过联想电脑管家下载 * 2. 安装Git(一路点击Next即可) * 3. 验证Git是否安装成功 * 4. 设置个人信息(名字和邮箱) 1. 下载Git安装包 1.1 通过清华大学开源软件镜像站下载(推荐) 下载地址:https://mirrors.tuna.tsinghua.edu.cn/github-release/git-for-windows/git/ https://mirrors.tuna.tsinghua.edu.cn/github-release/git-for-windows/git/ 点击 LatestRelease/ 目录 下载

By Ne0inhk