手撕各种排序(上)

简介: 手撕各种排序

> 作者简介:დ旧言~,目前大一,现在学习Java,c,c++,Python等

> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:掌握每种排序的方法,理解每种排序利弊和复杂度。

> 毒鸡汤:船停在码头是最安全的,但那不是造船的目的;人呆在家里是最舒服的,但那不是人生的意义。最美好的生活方式,莫过于和一群志同道合的人奔跑在理想的路上!

> 望小伙伴们点赞👍收藏✨加关注哟💕💕

🌟前言

       谈起排序这个事情,大家都是耳熟能详的事了,从我们认识的斗地主,每一复牌都是按照从小到大的顺序排序的,如图:


      排序的目的是为了让我们很好的管理,使无序的事情变成有序,当然排序的方法有很多,如由大到小,由大到小.....。而面对大量数据就需要排序。在数据结构中我们发明了多种排序,如我们最早认识的冒泡排序,本篇博客让大家对多种排序有一个很好的认知,闲话少谈。

主体  

咱们就掌握八种就行啦


🌙冒泡排序

这里博主在C语言刷题训练专栏中讲到过冒泡排序,咱们再回顾回顾


这里我们以接口的形式写代码,那咱们上代码咯


//冒泡排序测试
void BubbleSort(int* a, int n)
{
  for (int i = 0; i < n - 1; i++)
  {
    int exchange = 0;
    for (int j = 1; j < n - i; j++)
    {
      if (a[i - 1] > a[i])
      {
        //这里是一个交换函数
        Swap(&a[i - 1], &a[i]);
        exchange = 1;
      }
    }
    //这里进行一趟有序时,直接跳出循环
    if (exchange == 0)
    {
      break;
    }
  }
}

注意事项:

💦1.我们知道当给的数据有序时,就不再需要进行循环了,直接跳出循环(exchange作用)。

💦2. 第二个循环中  j < n - i  不能搞错。

时间复杂度:O(N²)

空间复杂度:O(1)

稳定性:稳定

复杂性:简单

🌙直接插入排序

     直接插入排序是一种简单的插入排序法,其基本思想是: 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 ,就好像我们斗地主拿牌插入相似。


咱们看看一个动态的插入动作。


这里我们以接口的形式写代码,那咱们上代码咯


//插入排序
void InsertSort(int* a, int n)
{
  for (int i = 0; i < n - 1; i++)
  {
    int end = i;
    int tmp = a[end + 1];
    //一个元素进行插入
    while (end >= 0)
    {
      if (tmp < a[end])
      {
        a[end + 1] = a[end];
      }
      else
      {
        break;
      }
      --end;
    }
    //最后把插入的元素赋值回去
    a[end + 1] = tmp;
  }
}

注意事项:

💦1.我们先进行第end个元素移动,再进行n个元素进行移动。

💦2. 最后需要a[end + 1] = tmp赋值

时间复杂度:O(N²)

空间复杂度:O(1)

稳定性:稳定

复杂性:简单

🌙希尔排序

      希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。咱们看看下面的图解:



在看看一个动态的图解:


 这里我们以接口的形式写代码,那咱们上代码咯

//希尔排序测试
void ShellSort(int* a, int n)
{
  int gap = n;
  while (gap > 1)
  {
    //间隔gap的元素进行排序
    gap = gap / 3 + 1;
    //本质上是插入排序
    for (int i = 0; i < n - gap; ++i)
    {
      int end = i;
      int tmp = a[end + gap];
      //一个元素进行插入
      while (end >= 0)
      {
        if (tmp < a[end])
        {
          a[end + gap] = a[end];
          end = end - gap;
        }
        else
        {
          break;
        }
      }
      //最后把插入的元素赋值回去
      a[end + gap] = tmp;
    }
  }
}

注意事项:

💦1.首先先嵌套一个插入排序,再把分组的元素进行交换。

💦2. gap = gap / 3 + 1这个不要忘记。

时间复杂度:O(N¹·²³)

空间复杂度:O(1)

稳定性:不稳定

复杂性:复杂


手撕各种排序(中):https://developer.aliyun.com/article/1389401

目录
相关文章
|
关系型数据库 数据库 Python
Python连接DB2数据库
Python连接DB2数据库
223 0
|
11月前
|
算法 Go Python
获取指定范围符合正态分布的随机数Go/Python
获取指定范围符合正态分布的随机数Go/Python
150 0
|
9月前
|
Kubernetes 网络协议 API
OpenAI全球宕机思考:谈谈可观测采集稳定性建设
文章探讨了为什么大规模集群中的可观测性服务会产生大量API请求、API服务器为何对DNS解析至关重要以及故障恢复过程为何缓慢的原因。
295 12
|
11月前
|
消息中间件 监控 Java
RocketMQ 同步发送、异步发送和单向发送,如何选择?
本文详细分析了 RocketMQ 中同步发送、异步发送和单向发送三种消息发送方式的原理、优缺点及适用场景。同步发送可靠性高但延迟较大,适合订单系统等场景;异步发送非阻塞且延迟低,适用于实时数据处理等场景;单向发送高效但可靠性低,适用于日志收集等场景。文章还提供了示例代码和核心源码分析,帮助读者更好地理解每种发送方式的特点。
1605 4
|
10月前
|
XML 编解码 前端开发
svg和canvas的区别
【10月更文挑战第24天】SVG和Canvas各有优缺点,在实际应用中需要根据具体的需求和场景来选择合适的技术来实现图形绘制和交互效果。
335 62
|
9月前
|
IDE 开发工具
【开发IDE升级】如何对IDEA版本进行升级
本文介绍了如何将 IntelliJ IDEA Ultimate 从 2020.2.2 版本升级到 2022.3.2 版本。主要内容包括准备工作、卸载旧版本和安装新版本的步骤。首先,从官网下载所需版本并备份旧版配置;接着,通过 Uninstall.exe 卸载旧版,保留配置和插件;最后,安装新版并完成激活。详细的操作步骤和截图帮助用户顺利完成升级过程。
10477 1
【开发IDE升级】如何对IDEA版本进行升级
|
10月前
|
SQL druid 数据库
如何进行数据库连接池的参数优化?
数据库连接池参数优化包括:1) 确定合适的初始连接数,考虑数据库规模和应用需求;2) 调整最大连接数,依据并发量和资源状况;3) 设置最小空闲连接数,平衡资源利用和响应速度;4) 优化连接超时时间,确保系统响应和资源利用合理;5) 配置连接有效性检测,定期检查连接状态;6) 调整空闲连接回收时间,适应访问模式并配合数据库超时设置。
|
存储 安全 IDE
电脑开机时报错No Bootable Device找不到索引的解决方法
【9月更文挑战第1天】当电脑开机时报错 “no bootable device”(找不到可引导设备),可能原因包括硬件连接问题、引导顺序设置错误、系统引导文件损坏及 BIOS 设置问题。解决方法有检查硬盘连接与状态、调整 BIOS 引导顺序、使用安装盘修复引导文件、检查硬盘模式设置及恢复 BIOS 默认设置等。若问题依旧,建议寻求专业维修帮助,并备份重要数据。
3995 8
新版Jadx 加载dex报错 jadx.plugins.input.dex.DexException:Bad checksum 解决方法
新版Jadx 加载dex报错 jadx.plugins.input.dex.DexException:Bad checksum 解决方法
|
算法 容器
【算法】双指针
【算法】双指针