排序算法之梳排序

news2024/9/23 1:25:54

title: 梳排序
date: 2024-7-30 14:46:27 +0800
categories:

  • 排序算法
    tags:
  • 排序
  • 算法
  • 梳排序
    description: 梳排序(Comb Sort)是一种由弗拉基米尔·多博舍维奇(Wlodzimierz Dobosiewicz)于1980年所发明的不稳定排序算法,并由史蒂芬·莱西(Stephen Lacey)和理查德·博克斯(Richard Box)于1991年四月号的Byte杂志中推广。梳排序是改良自冒泡排序和快速排序,其要旨在于消除“乌龟”,亦即在数组尾部的小数值,这些数值是造成冒泡排序缓慢的主因。相对地,“兔子”,亦即在数组前端的大数值,不影响冒泡排序的性能。
    math: true

梳排序

梳排序(Comb Sort)是一种改进的冒泡排序算法。它通过消除“乌龟”(即数组中的小值)和“兔子”(即数组中的大值)来提高排序效率。梳排序的核心思想是先使用较大的间隙(gap)进行比较和交换,然后逐渐减小间隙,最终进行常规的冒泡排序。

梳排序的原理

梳排序的关键在于间隙的选择和逐渐缩小。初始间隙通常设置为数组长度,然后在每次迭代中将间隙除以一个因子(通常为1.3),直到间隙缩小到1,此时进行最后的冒泡排序。

图示

在这里插入图片描述

梳排序的步骤

  1. 设置初始间隙:初始间隙为数组长度。
  2. 调整间隙:在每次迭代中,将间隙除以因子(通常为1.3)。
  3. 比较和交换:在当前间隙下比较并交换元素。
  4. 重复步骤2和3:直到间隙缩小到1,进行最后的冒泡排序。

梳排序示例

假设待数组[10 4 3 9 6 5 2 1 7 8]

第一次循环

待排数组长度为10,而10÷1.3=8,则比较10和7,4和8,并做交换
交换后的结果为[7 4 3 9 6 5 2 1 10 8]

第二次循环

更新间距为8÷1.3=6,比较7和2,4和1,3和10,9和8,7和2,4和1,9和8,需要交换
交换后的结果为[2 1 3 8 6 5 7 4 10 9]

第三次循环

更新距离为4,比较2和6,1和5,3和7,8和4,6和10,5和9,8和4,需要交换
[2 1 3 4 6 5 7 8 10 9]

第四次循环

更新距离为3,比较2和4,1和6,3和5,4和7,6和8,5和10,7和9,不需要交换

第五次循环

更新距离为2,比较2和3,1和4,3和6,4和5,6和7,5和8,7和10,8和9,不需要交换

第六次循环

更新距离为1,为冒泡排序。

[1 2 3 4 5 6 7 8 9 10]

交换后排序结束,顺序输出即可得到[1 2 3 4 5 6 7 8 9 10]

复杂度分析

递减率的设置影响着梳排序的效率,原作者以随机数作实验,得到最有效递减率为1.3的。如果此比率太小,则导致一循环中有过多的比较,如果比率太大,则未能有效消除数组中的乌龟。

亦有人提议用 1 / ( 1 − 1 e φ ) ≈ 1.247330950103979 1/\left(1-{\frac {1}{e^{\varphi }}}\right)\approx 1.247330950103979 1/(1eφ1)1.247330950103979作递减率,同时增加换算表协助于每一循环开始时计算新间距。

因为编程语言中乘法比除法快,故会取递减率倒数与间距相乘, 1 1.247330950103979 = 0.801711847137793 ≈ 0.8 \frac{1}{1.247330950103979}=0.801711847137793\approx 0.8 1.2473309501039791=0.8017118471377930.8

时间复杂度

  • 最佳情况 O ( n log ⁡ n ) O(n\log n) O(nlogn)
  • 最坏情况 Ω ( n 2 ) \Omega(n^2) Ω(n2)
  • 平均情况 Ω ( n 2 2 p ) \Omega (\frac{n^2}{2^p}) Ω(2pn2)

空间复杂度

  • 空间复杂度 O ( 1 ) O(1) O(1)

Java代码实现

import java.util.Arrays;

public class CombSort {

    public static void combSort(int[] arr) {
        int n = arr.length;
        int gap = n;
        boolean swapped = true;

        while (gap != 1 || swapped) {
            // 调整间隙
            gap = getNextGap(gap);
            swapped = false;

            // 比较和交换
            for (int i = 0; i < n - gap; i++) {
                if (arr[i] > arr[i + 1]) {
                    int temp = arr[i];
                    arr[i] = arr[i + gap];
                    arr[i + gap] = temp;
                    swapped = true;
                }
            }
        }
    }

    // 计算下一个间隙
    private static int getNextGap(int gap) {
        gap = (gap * 10) / 13;
        if (gap < 1) {
            return 1;
        }
        return gap;
    }

    public static void main(String[] args) {
        int[] arr = {6, 4, 3, 7, 1, 9, 8, 2, 5};
        System.out.println("Given Array:");
        System.out.println(Arrays.toString(arr));

        // 调用梳排序函数
        combSort(arr);

        System.out.println("Sorted Array:");
        System.out.println(Arrays.toString(arr));
    }
}

变异形式

梳排序-11

设置递减率为1.3时,最后只会有三种不同的间距组合:(9, 6, 4, 3, 2, 1)、(10, 7, 5, 3, 2, 1)、或 (11, 8, 6, 4, 3, 2, 1)。实验证明,如果间距变成9或10时一律改作11,则对效率有明显改善,原因是如果间距曾经是9或10,则到间距变成1时,数值通常不是递增序列,故此要进行几次冒泡排序循环修正。加入此指定间距的变异形式称为梳排序-11(Combsort11)_。

混合梳排序和其他排序算法

如同快速排序和归并排序,梳排序的效率在开始时最佳,接近结束时最差。如果间距变得太小时(例如小于10),改用插入排序或希尔排序等算法,可提升整体性能。

此方法最大好处是不需要检查是否进行过交换程序以将排序循环提早结束。

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

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

相关文章

无字母绕过webshell

目录 代码 payload构造 php7 php5 构造payload 代码 不可以使用大小写字母、数字和$然后实现eval的注入执行 <?php if(isset($_GET[code])){$code $_GET[code];if(strlen($code)>35){die("Long.");}if(preg_match("/[A-Za-z0-9_$]/",$code))…

工业边缘网关软件 NeuronEX 中基于角色的访问控制功能

随着企业数字化转型的不断深入&#xff0c;确保数据和信息安全变得日益重要。传统的访问控制方法往往需要为每个用户单独配置权限&#xff0c;这种方法管理复杂且漏洞百出&#xff0c;难以适应快速变化的业务需求。而基于角色的访问控制&#xff08;RBAC&#xff09;功能通过定…

主任务控制子任务通信流程

#define WM_TAKE_STOCK_CMD 172 //MAIN->TAKE 任务流程#define TAKE_STOCK_CMD_FIND_TRAY 1 // 找托盘 #define WM_TAKE_STOCK_CMD_EXC 173 //TAKE内部使用#define TAKE_STOCK_EXE_OK 0 #define WM_TAKE_STOCK_TASK_MSG 174 //MAIN->TAKE 发送…

数据结构+图的基本应用

一、问题描述 求有向图的简单路径 编写一个程序&#xff0c;设计相关算法完成以下功能。 &#xff08;1&#xff09;输出如图所示的有向图 G 从顶点 5 到顶点 2 的所有简单路径。 &#xff08;2&#xff09;输出如图所示的有向图 G 从顶点 5 到顶点 2 的所有长度为 3 的简单…

Qt编译配置OpenCV+opencv_contrib(使用cmake)

本文使用环境 OpenCV: 4.7.0 cmake: 3.30.2 Qt: 5.12.1一、配置环境变量 安装好OpenCV、Qt、cmake后&#xff0c;应配置好一下环境变量&#xff1a; 二、编译OpenCV 打开cmake&#xff0c;编译的源码路径选择opencv文件夹中的sources目录&#xff0c;在opencv文件夹下新建一…

代码随想录 day 38 动态规划

第九章 动态规划part06 322. 零钱兑换 如果求组合数就是外层for循环遍历物品&#xff0c;内层for遍历背包。 如果求排列数就是外层for遍历背包&#xff0c;内层for循环遍历物品。 这句话结合本题 大家要好好理解。 视频讲解&#xff1a;https://www.bilibili.com/video/BV14K…

【自用】Python爬虫学习(六):通过m3u8文件下载ts文件并合并为.mp4文件

Python爬虫学习&#xff08;六&#xff09; 下载视频&#xff08;简单版&#xff09;的步骤介绍第一步&#xff1a;在网页上找到.m3u8文件第二步&#xff1a;通过.m3u8文件下载对应的.ts视频文件第三步&#xff1a;依据.m3u8文件合并.ts文件为一个.mp4文件 下载视频&#xff08…

stm32智能颜色送餐小车(oled显示压力传感器重量)

大家好啊&#xff0c;我是情谊&#xff0c;今天我们来介绍一下我最近设计的stm32产品&#xff0c;我们在今年七月份的时候参加了光电设计大赛&#xff0c;我们小队使用的就是stm32的智能送餐小车&#xff0c;虽然止步于省赛&#xff0c;但是还是一次成长的经验吧&#xff0c;那…

PyQt编程快速上手

Python GUI安装 GUI就是图形用户界面的意思&#xff0c;在Python中使用PyQt可以快速搭建自己的应用&#xff0c;使得自己的程序看上去更加高大上&#xff0c;学会GUI编程可以使得自己的软件有可视化的结果。 如果你想用Python快速制作界面&#xff0c;可以安装PyQt&#xff1a…

Linux云计算 |【第二阶段】NETWORK-DAY6

主要内容&#xff1a; 企业网络综合项目分析、大型企业网络搭建 项目案例1 一家网络公司&#xff0c;有若干服务器&#xff0c;通过NAT技术将业务服务器与Internet互联&#xff1b;已有技术&#xff1a; ① 默认路由&#xff1a;实现到互联网数以万计网络访问的简化配置&…

Elasticsearch自动补全功能实践与Java API应用

Elasticsearch是一个强大的搜索引擎&#xff0c;它不仅支持全文搜索&#xff0c;还提供了自动补全功能&#xff0c;可以显著提升用户体验。自动补全功能允许用户在输入查询时实时显示建议项&#xff0c;帮助用户快速找到所需信息。本文将介绍如何使用Elasticsearch的RestHighLe…

配置Google API,用JavaScript和Python读取Google sheet里的数据

[发布时间是2024年8月。技术流程可能会存在一些变动] 源代码可以参考&#xff1a;victorspaceRMW/Read-Google-Sheet-with-API: The source code to read the Google Sheet with Google cloud API (github.com) 开头提醒一下各位公司&#xff0c;国内包括腾讯云华为云阿里云&…

echarts使图表组件根据屏幕尺寸变更而重新渲染大小

效果图&#xff1a; 通过 window.addEventListener(resize, this.resizeChart); 实现 完整代码&#xff1a; <template><div class"dunBlock"><div class"char2" id"char2" ref"chart"></div></div…

《光与夜之恋》3D建模含量超标,纯炫技还是释放新信号?

继叠纸的《恋与深空》之后&#xff0c;腾讯的《光与夜之恋》也卷起3D技术了。 《光与夜之恋》即将在8月12日上线的限定活动“大漠归墟”最新PV及男主六星卡面释出&#xff0c;相对于褒贬不一、引起争论的卡面美术&#xff0c;PV中的3D建模倒是收获了玩家的集体好评。 “大漠归…

读零信任网络:在不可信网络中构建安全系统18零信任代理

1. 零信任代理 1.1. 零信任代理是应用级代理服务器&#xff0c;用来保护零信任网络&#xff0c;它是处理认证、授权以及加密的基础设施 1.2. 零信任代理分为反向代理和前向代理两种工作模式 1.2.1. 运行时可以同时采用这两种工作模式&#xff0c;也可以只采用其中的一种 1.2…

libcurl8.9.1 上传json

在postman中 PUT----》body----》raw----》json 结构体定义&#xff1a; #define MAX_ARRAY_SIZE 5*1024*1024struct SMART_DATA_CACHE {char* buf;long dwTotalLen;SMART_DATA_CACHE(){dwTotalLen 0;buf nullptr;while (!buf) {try {buf new char[MAX_ARRAY_SIZE];}c…

C++:有序关联容器set

什么是有序关联容器 (1)顺序容器&#xff0c;容器中的元素是按它们在容器中的位置来顺序保存和访问的(可以理解是数组) (2)顺序容器有array、vector、deque、list、forward_list、string等 (3)关联容器中的元素是按关键字来保存和访问的&#xff0c;关联的意思就是关键字&…

STM32-外部中断-AFIO-串口-串口通信-串口中断(空闲中断和接收中断)-printf移植-ADC数模转换-初始化和读取光敏电阻AO

常用的中断包括外部中断、串口中断、定时器中断&#xff1b; 1、外部中断&#xff1a; 引脚复用按钮导致的外部中断&#xff1a; 注意&#xff1a;初始化引脚&#xff0c;添加引脚和EXTI输入线的映射&#xff1b;使用外部引脚的中断时需要使用AFIO映射&#xff1b; 操作步骤&…

如何获取android的SHA1或SHA256

在使用地图类的功能时&#xff0c;例如百度地图或者高德地图&#xff0c;会需要在开发者平台里填写SHA1或SHA256的指纹密钥&#xff0c;很多开发者小伙伴还不知道如何获取。当然关于如何获取android的SHA1或SHA256&#xff0c;网络上进行搜索已经有很多图文教程了&#xff0c;本…

mfc140u.dll丢失的科学修复手段,简单又方便的mfc140u.dll修复

遇到 "缺失 mfc140u.dll 文件" 的提示时可能会让你疑惑&#xff0c;但不用担心。这个文件是 Microsoft Visual C 2015 的重要组成部分&#xff0c;对运行特定程序非常关键。幸运的是&#xff0c;解决这一问题并不难。本文将简单指导你如何恢复或修复丢失的 mfc140u.d…