【例题】lanqiao4403 希尔排序模板题
插入排序每次只能将数据移动一位。
已知插入排序代码为:
def insert_sort(a):for i in range(1,len(a)):j=i-1while j>=0 and a[j]>a[i]:a[j+1]=a[j]j-=1a[j+1]=a[i]return a
希尔排序在插入排序的基础上,将数据移动n/2,n/4,…,1位。
for i in range(gap, n):
temp = a[i]
:把a[i]的值赋给temp,用于比较
j = i
j指针从i开始,表示的是从后往前遍历比大小的下标。
当j >= gap(为了确保后面的j-gap下标还在数组索引里,不会超出范围) and a[j - gap] > temp(j-temp对应的数大于j对应的数,把j-gap的数放到原来的j的位置,然后再往前对比)
:
此时j下标对应的数是原来j-gap对应的数:
a[j] = a[j - gap]
因为根据插入排序原理,把要插入的数的大小temp跟前面已经排序好的数以步长为1( j -= 1
)从后往前进行对比,希尔排序也是把要插入的数的大小temp跟前面已经排序好的数从后往前对比,但是是以步长为gap往前遍历。所以: j -= gap
跳出while
循环的条件是已经把前面gap步长遇到的所有值排好序了,而且原来的a[j]=a[j-gap]
是把j-gap比temp大的值放到了j的位置,那原来的j-gap的位置就空了出来,j-=gap
操作后,原来的j-gap就是新的j的位置,把temp放到这个位置:a[j] = temp
。实现了如果a[j - gap] > temp
(a[i]),那么交换位置的操作。
用gap //= 2
不断缩小步长,直到gap=1跟插入排序一致,此时所有数据顺序都排好了。
比如有一组示例数据如下
7 | 2 | 9 | 1 | 5 | 4 | 6 |
---|
a
数组长度是7
这里的gap初始值是7//2=3
a[i]初始值从3开始,a[3]=1。
接下来就是以gap的步长往前遍历,把数组分为4组:
a[j-temp] temp
7 1
2 6
9 4
1 6
然后进行对比,如果a[j - gap] > temp
,交换位置。
这样处理后的数组为:
1 | 2 | 4 | 7 | 5 | 9 | 6 |
---|
gap //= 2
,gap=1。
a[i]初始值从1开始,a[1]=2。
接下来就是以gap的步长往前遍历比大小:
a[j-temp] temp
1 2
# 1247596
--------------
2 4
1 4
# 1247596
--------------
4 7
2 7
1 7
# 1247596
--------------
7 5
# 5,7互换
4 5
2 5
1 5
# 1245796
--------------
7 9
5 9
4 9
2 9
1 9
# 1245796
--------------
9 6
# 6,9互换
7 6
# 6,7互换
5 6
4 6
2 6
1 6
# 1245679
然后进行对比,如果a[j - gap] > temp
,交换位置。
这样处理后的数组为:
1 | 2 | 4 | 5 | 6 | 7 | 9 |
---|
def shell_sort(a):n = len(a)gap = n // 2while gap > 0:for i in range(gap, n):temp = a[i]j = iwhile j >= gap and a[j - gap] > temp:a[j] = a[j - gap]j -= gapa[j] = tempgap //= 2
希尔排序(Shell Sort)比插入排序(Insertion Sort)更高效的原因是因为希尔排序通过使用间隔序列在排序过程中引入了数据交换的“跳跃”。这种跳跃允许算法在内部循环中进行更远距离的交换,从而减少了元素比较和移动的次数。
对比代码如下:
import random
import timedef insertion_sort(arr):comparisons = 0moves = 0for i in range(1, len(arr)):key = arr[i]j = i - 1while j >= 0 and key < arr[j]:comparisons += 1arr[j + 1] = arr[j]moves += 1j -= 1comparisons += 1arr[j + 1] = keyreturn comparisons, movesdef shell_sort(arr):comparisons = 0moves = 0gap = len(arr) // 2while gap > 0:for i in range(gap, len(arr)):temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:comparisons += 1arr[j] = arr[j - gap]moves += 1j -= gapcomparisons += j >= gaparr[j] = tempgap //= 2return comparisons, moves# 生成随机数组
array_size = 1000
random_array = [random.randint(1, 10000) for _ in range(array_size)]# 复制数组以保持原始数组不变
insertion_array = random_array.copy()
shell_array = random_array.copy()# 插入排序
start_time = time.time()
insertion_comparisons, insertion_moves = insertion_sort(insertion_array)
insertion_time = time.time() - start_time# 希尔排序
start_time = time.time()
shell_comparisons, shell_moves = shell_sort(shell_array)
shell_time = time.time() - start_timeprint(f"Insertion Sort: Comparisons={insertion_comparisons}, Moves={insertion_moves}, Time={insertion_time:.6f}s")
print(f"Shell Sort: Comparisons={shell_comparisons}, Moves={shell_moves}, Time={shell_time:.6f}s")
Insertion Sort: Comparisons=245538, Moves=244539, Time=0.035560s
Shell Sort: Comparisons=14866, Moves=7356, Time=0.000997s
相关文章:

【例题】lanqiao4403 希尔排序模板题
插入排序每次只能将数据移动一位。 已知插入排序代码为: def insert_sort(a):for i in range(1,len(a)):ji-1while j>0 and a[j]>a[i]:a[j1]a[j]j-1a[j1]a[i]return a希尔排序在插入排序的基础上,将数据移动n/2,n/4,…,1位。 for i in range(ga…...

【C/C++】速通涉及string类的经典编程题
【C/C】速通涉及string类的经典编程题 一.字符串最后一个单词的长度代码实现:(含注释) 二.验证回文串解法一:代码实现:(含注释) 解法二:(推荐)1. 函数isalnum…...

MySQL:库表的基本操作
库操作 查看 查看存在哪些数据库: show databases;查看自己当前处于哪一个数据库: select database(); 由于我不处于任何一个数据库中,此处值为NULL 查看当前有哪些用户连接到了MySQL: show processlist; 创建 创建一个数据库 语…...

JS领域的AI工程利器分享
JavaScript,这个在网页开发中广为人知的脚本语言,正逐渐在AI工程领域展现出其独特的魅力。对于那些希望将大语言模型(LLM)融入项目的开发者来说,以下五个JavaScript工具将是关键资源。 1. TensorFlow.js TensorFlow.…...

2024/9/20 使用QT实现扫雷游戏
有三种难度初级6x6 中级10x10 高级16x16 完成游戏 游戏失败后,无法再次完成游戏,只能重新开始一局 对Qpushbutton进行重写 mybutton.h #ifndef MYBUTTON_H #define MYBUTTON_H #include <QObject> #include <QWidget> #include <QPus…...

09.20 C++对C的扩充以及C++中的封装、SeqList
SeqList.h #ifndef SEQLIST_H #define SEQLIST_H#include <iostream> #include<memory.h> #include<stdlib.h> #include<string.h>using namespace std;//typedef int datatype; //类型重命名 using datatype int;//封装一个顺序表 class Seq…...

Git提交类型
说明:Git提交类型指的是代码commit时,写在comment前面的标志,表示此次commit的提交类型,如下: Git提交类型 常见的Git提交类型有: feat:新特性、新功能或优化; fix:修复…...

C++速通LeetCode简单第18题-杨辉三角(全网唯一递归法)
全网唯一递归法: vector<vector<int>> generate(int numRows) {vector<int> v;vector<vector<int>>vn;if (numRows 1){v.push_back(1);vn.push_back(v);v.clear();return vn;//递归记得return}if (numRows 2){v.push_back(1);vn.p…...

Redis作为单线程模型,为什么效率高、速度快呢?
前言: 效率高、速度快是相较于数据库来说的(MySQL、Orcale、SQL server) 文章目录 一、单线程模式的工作流程二、为什么快? 一、单线程模式的工作流程 这里我们所说的单线程是指:Redis只使用一个线程,来处…...

人工智能——猴子摘香蕉问题
一、实验目的 求解猴子摘香蕉问题,根据猴子不同的位置,求解猴子的移动范围,求解对应的过程,针对不同的目标状态进行求解。 二、实验内容 根据场景有猴子、箱子、香蕉,香蕉挂天花板上。定义多种谓词描述位置、状态等…...

对ViT 中Patch Embedding理解
借鉴了这个博主的ViT Patch Embedding理解-CSDN博客,再加了一些理解。 就通过代码来理解吧 假设输入图像的维度为HxWxC,分别表示高,宽和通道数。 PatchEmbed 的类,它继承了 nn.Module,实现了将输入的2维图像&#…...

Redis基本命令详解
1. 基本命令 命令不区分大小写,而key是区分大小写的 # select 数据库间的切换 数据库共计16个 127.0.0.1:6379> select 1# dbsize 返回当前数据库的 key 的数量 127.0.0.1:6379[1]> dbsize# keys * 查看数据库所有的key 127.0.0.1:6379[1]> keys *# fl…...

Java之线程篇四
目录 volatile关键字 volatile保证内存可见性 代码示例 代码示例2-(volatile) volatile不保证原子性 synchronized保证内存可见性 wait()和notify() wait()方法 notify() 理解notify()和notifyAll() wait和sleep的对比 volatile关键字 volati…...

计算机毕业设计之:基于微信小程序的校园流浪猫收养系统
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...

SpringBoot:关于Redis的配置失效(版本问题)
我们使用redis时发现yaml配置中的redis相关配置不生效,后面发现将配置修改甚至删除所有相关redis的配置,springboot依然能使用redis里面默认的db0并且不报错。上网查阅了一些文章,也都没有解决今天分享下,我的处理方法, SpringBo…...

halcon 快速定义字典
定义一个名为params的字典 Params : dict{} 等价于用 create_dict (Params ) 为字典添加键值对,在halcon中箭只能是字符串,值可以是任何类型的obj或者tuple Params.remove_outer_edges : true Params.max_gap : 150 等价于用 set_dict_object (true,…...

Sublime text3怎么关闭提示更新
问题 sublime text 3有新版本后,会不停地在每次启动后弹窗提示更新版本 第一步 软件安装之前,切记是软件安装之前!!!需要在hosts中添加以下内容(屏蔽官网联网检测):hosts的位置一般在C:\Windows\System32\drivers\etc…...

生成式语言模型技术栈
生成式语言模型的最新技术栈正在快速发展,尤其是随着大规模预训练模型(LLMs)和生成式AI的应用不断扩展。以下是当今最前沿的生成式语言模型技术栈,涵盖从模型开发到优化、推理和部署的各个环节。 1. 基础模型开发 基础模型开发包…...

进程分析工具Process Explorer使用
进程分析工具Process Explorer使用 Process Explorer让使用者能了解看不到的在后台执行的处理程序,能显示目前已经载入哪些模块,分别是正在被哪些程序使用着,还可显示这些程序所调用的DLL进程,以及他们所打开的句柄。Process Expl…...

vue 中如何实现鼠标拖动出发滚动条的跟随移动?
使用场景 在做弹窗、表单或 tab 切换需求的时候,有时候因为内容过长会导致出现滚动条,但是只能拖动滚动条时会导致操作不便,我们会希望实现通过拖动内容区实现滚动条的滑动。这样操作就会简单多了。 实现思路 如果要实现鼠标辅助触发滚动条…...

【Java EE】文件IO
Author:MTingle major:人工智能 --------------------------------------- Build your hopes like a tower! 目录 一、文件是什么? 二、针对文件系统操作的API 1.文件路径,文件名,文件是否存在 2. 创建文件 3.删除文件&#…...

使用 React、Material-UI、Spring、MySQL、MyBatis 以及高德 API 模拟实时位置信息
要使用 React、Material-UI、Spring、MySQL、MyBatis 以及高德 API 模拟实时位置信息,你可以按以下步骤来实现: 目录 1. 前端 (React Material-UI) 2. 后端 (Spring Boot MyBatis MySQL) 3. 模拟实时位置数据 4. 前后端联调 1. 前端 (React Mat…...

UniApp一句话经验: px -> rpx动态转换和动态元素区域的获取
px->rpx转换 在多终端条件下,什么devicePixelRatio,upx2px都是不靠谱的,最直接的是这样: const { screenWidth } uni.getSystemInfoSync()const pixelUnit screenWidth / 750 // rpx->px比例基数 动态元素区域获取 多终…...

Python基于flask框架的智能停车场车位系统 数据可视化分析系统fyfc81
目录 技术栈和环境说明解决的思路具体实现截图系统设计python语言django框架介绍flask框架介绍性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示技术路线操作可行性详细视频演示源码获取 技术栈和环境说明 结合用户的使用需求&…...

海外服务器哪个速度最快且性能稳定
海外服务器的速度与性能稳定性受多种因素影响,包括地理位置、网络架构、基础设施质量以及用户网络路径等。在众多选择中,几个特定地区的服务器因其卓越表现而备受推崇。 首先,美国硅谷(加利福尼亚州)与纽约的服务器以其技术领先、网络连接稳定…...

C/C++通过CLion2024进行Linux远程开发保姆级教学
目前来说,对Linux远程开发支持相对比较好的也就是Clion和VSCode了,这两个其实对于C和C语言开发都很友好,大可不必过于纠结使用那个,至于VS和QtCreator,前者太过重量级了,后者更是不用说,主要用于…...

工程师 - 如何安装Windows 终端
Windows 终端是一款适用于 Windows 的现代命令行应用程序,支持多个终端会话,包括 Command Prompt、PowerShell 和 Windows Subsystem for Linux (WSL)。它具有标签式界面、可定制的设置(如主题和按键绑定)、改进的文本渲染以及对 …...

UniApp 从Vue2升级为Vue3需要注意哪些方面
Vue官方已经发布了Vue3,Vue2不再维护,也在建议大家都迁移到Vue3,所以Vue2终会被淘汰。 那么UniApp 从Vue2升级为Vue3需要注意哪些方面: 1、main.js 下面请看创建应用实例Vue2与Vue3的不同: Vue2的写法:…...

前端面试CSS常见题目
1. CSS 选择器的优先级 (Specificity) 面试官通常会问你如何计算 CSS 选择器的优先级,这对于避免样式冲突、提高代码可维护性很重要。 优先级计算规则: !important 优先级最高。内联样式(例如:<div style"color: red;&…...

408算法题leetcode--第10天
643. 子数组最大平均数 I 643. 子数组最大平均数 I思路:滑动窗口时间:O(n);空间:O(1) class Solution { public:double findMaxAverage(vector<int>& nums, int k) {double ret 0, temp 0;size_t size nums.size()…...