【排序】排序这样写才对Ⅱ -冒泡排序与快速排序Ⅰ

news2024/10/7 2:32:52

 

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法......感兴趣就关注我吧!你定不会失望。

🌈个人主页:主页链接

🌈算法专栏:专栏链接

     我会一直往里填充内容哒!

🌈LeetCode专栏:专栏链接 

    目前在刷初级算法的LeetBook 。若每日一题当中有力所能及的题目,也会当天做完发出

🌈代码仓库:Gitee链接

🌈点击关注=收获更多优质内容🌈

目录

0.常见的排序算法:

1.冒泡排序:

1.1冒泡排序代码实现:

1.2冒泡排序代码优化:

2.快速排序:

​编辑2.1Hore法:

2.2挖坑法:

 2.2.1挖坑法代码实现:

2.3双指针法:

2.3.1双指针法代码实现:        

2.4选取Key的方式:

2.4.1选择第一个:

2.4.2选择中间:

2.4.3三数取中:

完结撒花:


 

0.常见的排序算法:

常见的排序算法有这些.将会分成几个章节讲完,感兴趣的uu们可以关注下我的排序专栏,方便和后期观看.

这章重点讲交换排序中的:冒泡排序与快速排序.其中冒泡排序比较简单,而快速排序就有点困难了.话不多说我们开始

1.冒泡排序:

冒泡排序十分的简单,也是大多数朋友刚学习编程时就学会的排序方法.顾名思义:要排序的数就像一个气泡一样,一直往上冒,直到到达水面(也就是目标位置),每冒一次,下一次的气泡需要走的路程就-1,也就是水面下降.

其时间复杂度为O(N^2)

1.1冒泡排序代码实现:

void BubbleSort(int *a,int len)
{
    for(int i=0;i<len;i++)
        for(int j=1;j<len-i;j++)
        {
            if(a[j]>a[j-1])
            {
                swap(a[j],a[j-1]);
            }
        }
}

冒泡排序就写好啦,但这里可以优化一下:当剩下的数组有序的时候,还需要冒完全程嘛?

所以当有一次遍历发现一次都没有交换的时候,此时就可以推出冒泡.因为数组已经有序 

1.2冒泡排序代码优化:

void BubbleSort(int *a,int len)
{
    for(int i=0;i<len;i++)
     {      
        int exchage=1;
        for(int j=1;j<len-i;j++)
        {
            if(a[j]>a[j-1])
            {
                swap(a[j],a[j-1]);
                exchage=0;
            }
            
        }
        if(exchage)break;
     }
}

2.快速排序:

一听这个名字有没有觉得很高大,快速排序.

                                        我们通过一个动图来了解一下他是怎样工作

由浅入深,我们先来了解一下他单趟排序的过程.

首先先确定一个Key,这个时候一般是取第一个数字为key.

之后设定两个哨兵位,分别为左边第一个位置与右边第一个位置.

因为取定key的位置为.左边第一个.

所以要从右边先开始走.当右边遇到比key小的数字的时候就停下来.

这时候左边开始走,当遇到比key大的数字的时候.就停下来.

交换此时左边与右边所代表的数字

右边重新开始.重复这个过程.

直到两边相遇.将key和其交换即可.

(为什么相遇了交换则完成单趟排序以及解释下为什么要从key的对面开始走)

相遇了就说明,左边的都是比key小的.右边的都比key要大,则所以把key与当前这个位置交换就可以了

进而就可以解释为什么,要先从key的对面走.

因为要找比key小的,这样相遇的时候右边停留的才是比key小的(因为右边遇到小的先停下来)

之后再将其分为左半边与右半边进行上面的过程即可.

2.1Hore法:

刚刚介绍的这种方法就是Hore排序的方法,后面大部分的方法都是基于其基础上进行改进,所以我们先来看看他的代码实现

void PartSort1(int* a, int left, int right)//hore
{

    if(left>=right)return ;
    int key =left;
    int i=left,j=right;
    while(i<j)
    {
        while(i<j&&a[j]>=a[key])j--;
        while(i<j&&a[i]<=a[key])i++;
        if(i<j)swap(a[i],a[j]);
    }

    swap(a[key],a[i]);
    PartSort1(a,left,i-1);
    PartSort1(a,j+1,right);

}

注意,当中哨兵位寻找停下位置的时候,一定要加上等于的判断 ,否则当有一个数据等于key的值时,哨兵就会在这卡住.

2.2挖坑法:

其内容大致也与Hore法相似,不过是换了一种形式来进行排序.

先将Key作为坑挖出

之后右哨兵指向的位置(比key小的值)填入坑位中,转换坑位.

之后左哨兵指向的位置(比key大的值)填入坑位中,继续交互坑位

最后相遇的位置即为Key存入的位置

总的来说与Hore法大同小异.

不过与Hore法不同的是,必须先将Key的值保存下来(因为过程中产生了交换),否则最后填入的是交换后的值

 

 2.2.1挖坑法代码实现:

void PartSort3(int* a, int left, int right)//挖坑
{
    if(left>=right)return ;
    key=left;
    int begin=left,end=right;

    int value=a[begin];

    int hole=begin;

    while(begin<end)
    {
        while(begin<end&&a[end]>=value)end--;
        a[hole]=a[end];
        hole=end;
        while(begin<end&&a[begin]<=value)begin++;
        a[hole]=a[begin];
        hole=begin;
    }
    a[hole]=value;
    PartSort3(a,left,hole-1);
    PartSort3(a,hole+1,right);
}

2.3双指针法:

这个方法就与上面的有本质的区别了.先来看看动图理解下

其本质就是利用一段区间来维护比key大的数字.(用这个思想我们来理解下)

首先依旧先确定Key的值,因为prev与cur这段区间内维护的是比其大的值.

当cur指向的元素比key大的时候,直接后移cur,表示收入这段区间内

当cur指向元素比key小的时候,前移prev,此时指向的元素是区间内比key大的,与刚刚cur的元素进行一个交换.再前移cur.此时区间内仍然保持着都比key大的性质

2.3.1双指针法代码实现:        

void PartSort4(int* a, int left, int right)//双指针
{
    if(left>=right)return ;
    key=left;
    int prev=left,cur=left+1;
    while(cur<=right)
    {
        if(a[cur]<a[key]&&++prev!=cur)
        {
            swap(a[cur],a[prev]);
        }
        ++cur;
    }
    swap(a[prev],a[key]);
    PartSort4(a, left,prev-1);
    PartSort4(a, prev+1,right);
}

2.4选取Key的方式:

介绍几种常用选择Key的方式.

2.4.1选择第一个:

当key选择第一个的时候,有可能会出现这个数就是这里面最小/最大的,若出现这种情况,则会让排序效率下降.

2.4.2选择中间:

同样会出现上述的情况.

2.4.3三数取中:

将left,right,medium(left+right/2)对应的三个数进行比较.之后将中间值放到Left位上即可.

int getMedium(int *a,int left,int right)
{
    int medium=(left+right)>>1;
    if(a[left]>a[right])
    {
        if(a[medium]>a[right]&&a[medium]<a[left])
            return medium;
        else if(a[medium]<a[right])
            return right;
        else 
            return left;
    }
    //right>left 
    else {
        if(a[medium]>a[left]&&a[medium]<a[right])
            return medium;
        else if(a[medium]<a[left])
            return left;
        else
            return right;
    }
}
//调用getmedium的格式
int key =getMedium(a,left,right);
    if(a[key]!=a[left])swap(a[key],a[left]);

完结撒花:

🌈本篇博客的内容【排序这样写才对Ⅱ -冒泡排序与快速排序Ⅰ】已经结束。

🌈若对你有些许帮助,可以点赞、关注、评论支持下博主,你的支持将是我前进路上最大的动力。

🌈若以上内容有任何问题,欢迎在评论区指出。若对以上内容有任何不解,都可私信评论询问。

🌈诸君,山顶见!        

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

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

相关文章

【Spring6】| Spring6整合JUnit

目录 一&#xff1a;Spring6整合JUnit 1. Spring对JUnit4的支持 2. Spring对JUnit5的支持 一&#xff1a;Spring6整合JUnit 1. Spring对JUnit4的支持 准备工作&#xff1a;pom.xml 注&#xff1a;以前是直接使用单元测试Junit&#xff0c;现在使用Spring对Junit的整合&…

快递电子运单上,电话应隐藏6位以上,禁止显示这些信息

我国快递年业务量达千亿件&#xff0c;快递电子运单是应用于快递外包装的重要单据&#xff0c;每年耗用量很大。在强化个人信息保护方面&#xff0c;《快递电子运单》国家标准要求快递企业、电商经营主体等采取措施&#xff0c;避免在电子运单上显示完整的收寄件人个人信息。 …

【机器学习】P14 Tensorflow 使用指南 Dense Sequential Tensorflow 实现

Tensorflow 第一节&#xff1a;使用指南Tensorflow 安装神经网络一些基本概念隐藏层和输出层&#xff1a;神经元的输出公式Tensorflow 全连接层 Dense 与 顺序模型 SequentialDense LayerSequential Model代码实现一个神经网络实现方式一&#xff1a;手写神经网络* 实现方式二&…

JavaScript基础入门全解析(上)

JavaScript基础语法 什么是JavaScript&#xff08;简称js&#xff09; 1.首先了解前端页面的组成&#xff08;前端页面的三层结构&#xff09; ●HTML 表示了你的页面内有什么&#xff0c;组成页面的骨架 &#xff08;结构层&#xff09; ●CSS 表示了你的页面中每一个内容是…

Linux系统中安装新版本nacos(centos7)

1. 背景需求 由于一些限制,在客户现场的Linux操作系统中,没有安装docker k8s等容器,无法直接使用镜像安装,而且客户要求只能在原始的操作系统中安装最新版的nacos,(为什么需要安装最新版的nacos,因为检测国网检测到之前版本的nacos有漏洞,需要安装新版的nacos). 2. 下载nacos…

Windows10+Cmake+VS2019编译opencv

主要参考&#xff1a;Windows10CmakeVS2019编译opencv&#xff08;超级详细&#xff09;_vs编译opencv_乐安世家的博客-CSDN博客 OpenCV&#xff1a;Releases - OpenCV 想直接简单使用的话&#xff0c;不需要自己编译&#xff0c;下载编译好的就可以 假如需要用到opencv-contr…

【Python入门第四十九天】Python丨NumPy 数组拆分

拆分 NumPy 数组 拆分是连接的反向操作。 连接&#xff08;Joining&#xff09;是将多个数组合并为一个&#xff0c;拆分&#xff08;Spliting&#xff09;将一个数组拆分为多个。 我们使用 array_split() 分割数组&#xff0c;将要分割的数组和分割数传递给它。 实例 将数…

Docker教程:如何将Helix QAC创建为一个容器并运行?

在这个Docker教程中&#xff0c;你将了解到如何将Helix QAC创建为一个容器化的镜像并运行。 Docker的基本定义是一个开源且流行的操作系统级虚拟化&#xff08;通常称为“容器化”&#xff09;技术&#xff0c;它是轻量级且可移植的&#xff0c;主要在Linux和Windows上运行。D…

Linux主机 SSH 通过密钥登录

我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器。但是&#xff0c;一般的密码方式登录&#xff0c;容易有密码被暴力破解的问题。所以&#xff0c;一般我们会将 SSH 的端口设置为默认的 22 以外的端口&#xff0c;或者禁用 root 账户登录。其实&#xff0c;有一个更…

换电脑 NoteExpress 数据备份迁移

前言 主要操作是跟着这篇博客做的&#xff1a;NoteExpress数据库备份和转移。但也有一些不一样的地方 旧电脑NoteExpress(NE)版本3.7&#xff0c;新电脑版本3.8 旧电脑 导出配置文件 桌面找到图标&#xff0c;打开位置&#xff0c;点击配置备份&#xff08;绿色的图标&#…

水库安全运行智慧管理平台解决方案筑牢防汛“安全墙”

解决方案 水库安全运行智慧管理系统解决方案&#xff0c;系统主要由降雨量监测站、水库水位监测站、大坝安全监测中的渗流量、渗流压力和变形监测站及视频和图像监测站等站点组成&#xff0c;同时建立规范、统一的监测平台&#xff0c;集数据传输、信息共享、数据储存于一体&a…

图解HTTP阅读笔记:第4章 返回结果的HTTP状态码

《图解HTTP》第四章读书笔记 图解HTTP第4章&#xff1a;返回结果的HTTP状态码4.1 状态码告知从服务器端返回的请求结果4.2 2XX成功4.2.1 200 OK4.2.2 204 No Content4.2.3 206 Parital Content4.3 3XX重定向4.3.1 301 Moved Permanently4.3.2 302 Found4.3.3 303 See Other4.3.…

服务(第三篇)Apache配置与应用

httpd服务支持的虚拟主机类型包括以下三种: 1.基于域名&#xff1a;为每个虚拟主机使用不同的域名&#xff0c;但是其对应的 IP 地址是相同的。 2.基于IP地址&#xff1a;为每个虚拟主机使用不同的域名&#xff0c;且各自对应的IP地址也不相同。这种方式需要为服务器配备多个网…

Femto基站及其射频方案

关于部署3G femto基站 3GPP定义第三代移动通信的目的是要为客户提供全方位的移动多媒体体验。但很多条件下&#xff0c;这一目的并未实现&#xff0c;尤其是在边远地区或居民聚集区。 一个可行的解决方案是在家庭范围内部署无需宏node-B基站即可提供最大移动数据速率的家用基站…

26基于模型预测控制MPC的永磁同步电机MATLAB代码

资源地址&#xff1a; 基于模型预测控制&#xff08;MPC&#xff09;的永磁同步电机Matlab代码-电子商务文档类资源-CSDN文库 主要内容&#xff1a; 包含单电流环MPC仿真&#xff08;仅电流环使用MPC策略&#xff0c;速度环使用PI调节器&#xff09;、速度环和电流环MPC仿真…

C ++匿名函数:揭开C++ Lambda表达式的神秘面纱

潜意识编程&#xff1a;揭秘C Lambda表达式的神秘面纱 Subconscious Programming: Unveiling the Mystery of C Lambda Expressions 引言&#xff1a;Lambda表达式的魅力 (The Charm of C Lambda Expressions)Lambda表达式简介与基本概念 (Introduction and Basic Concepts of …

【Linux】浅析Input子系统

文章目录1. 框架1.1 数据结构1.2 evdev_handler1.3 evdev_init1.4 input_register_handler2. 应用如何打开节点并读取到事件数据2.1 evdev_fops2.2 evdev_open2.3 evdev_release2.4 evdev_read2.5 evdev_write2.6 evdev_poll2.7 evdev_fasync2.8 evdev_ioctl2.9 evdev_ioctl_co…

ADManager Plus:简化 Active Directory 管理的完美工具

在企业中&#xff0c;Active Directory&#xff08;AD&#xff09;是一个非常重要的组件&#xff0c;用于管理和控制所有计算机和用户的访问权限。然而&#xff0c;AD的管理和维护需要一定的技术能力和时间成本。为了简化这个过程&#xff0c;ManageEngine 推出了 ADManager Pl…

ASIC-WORLD Verilog(2)FPGA的设计流程

写在前面 在自己准备写一些简单的verilog教程之前&#xff0c;参考了许多资料----asic-world网站的这套verilog教程即是其一。这套教程写得极好&#xff0c;奈何没有中文&#xff0c;在下只好斗胆翻译过来&#xff08;加了自己的理解&#xff09;分享给大家。 这是网站原文&…

如何在 DevOps 中进行 API 全生命周期管理?

随着 DevOps 理念在中国企业当中的普及和发展&#xff0c;中国企业 DevOps 落地成熟度不断提升&#xff0c;根据中国信通院的数据已有近 6 成企业向全生命周期管理迈进。 而在研发全生命周期管理之中&#xff0c;API 管理的地位愈发显得重要。随着 API 数量的大幅增长&#xf…