九大排序之选择排序和归并排序

1.前言

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。

本章重点:

堆排序和选择排序和归并排序

2.选择排序

基本思路

  • left和right记录区间的左端和右端;

  • 不断遍历数组,经过一次遍历选出区间中的最大值和最小值;

  • 然后将最小值换到左端,最大值换到右端;

  • ++left; --right; 当left < right时循环继续。

 注意:交换元素时如果先后交换的下标恰好相同需要做出调整。

代码如下:

void SelectSrot(int *arr, int n){assert(arr != NULL);int begin = 0;int end = n-1;//begin,end向中间靠拢while (begin < end){int maxi = begin;int mini = begin;//一次循环找出一个最大值和一个最小值分别放到begin和end位置for (int i = begin; i <= end; i++){if (arr[i] < arr[mini]){mini = i;}if (arr[i] > arr[maxi]){maxi = i;}}//因为先将maxi和end交换,所以当后换的mini==end 时原来end的值已经被换走了,转换一下if (maxi == begin){maxi = mini;}Swap(&arr[begin], &arr[mini]);	Swap(&arr[end], &arr[maxi]);begin++;end--;}
}

 

  • 直接选择排序的特性总结:
    1. 选择排序思路简单好理解,但是对有序序列无反应,复杂度恒为O(N^2)。效率低,实际中很少使用。
    2. 时间复杂度:O(N^2)
    3. 空间复杂度:O(1)
    4. 稳定性:不稳定(有可能两个相等元素的相对顺序会发生变化)
    5. 数据敏感性:不敏感,不管有序无序都要进行多轮次的选择

2.堆排序

在写堆排序之前先写一个节点向上调整和节点向下调整

AdJustDown:

//向下调整,小的在上,大的在下
void AdjustDown(int *arr, int sz, int root)//父亲节点的下标
{assert(arr!=nullptr);int parent=root;int child=2*parent+1;//左节点while(child<sz){//先判断谁小---找小if(child+1<sz&&arr[child]<arr[child+1])child++;if(arr[child]<arr[parent]){swap(&arr[child],&arr[parent]);parent=child;child=2*parent+1;}else  break;}
}

AdJustUp:向上调整

//向上调整---大的在顶部
void  AdJustUp(int *arr,int sz,int root)//这里传来的是孩子节点
{assert(arr!=nullptr);int child=root;int parent=(child-1)/2;while(child<sz){if(arr[child]<arr[parent]){swap(&arr[child],&arr[parent]);child=parent;parent=(child-1)/2;}else break;}}

构建一个堆,一般来说都是从第一个非叶子节点开始构建堆。

void  HeapSort(int* arr,int sz)
{assert(arr!=nullptr);for(int i=(sz-1-1)/2;i>=0;i--){AdJustDown(arr,sz,i);}//大堆建立完了之后。开始排序for(int end=sz-1;end>=0;end--){swap(&arr[end],&arr[0]);//最大值调整到了最后一个,最小值调整到了第一个AdJustDown(arr,sz,0);//再把最小值进行调整}    
}

思路总结:

1.首先写一个向上调整或者向下调整函数

2.调整堆:如果是需要升序的话---那么就是大堆---大堆就是说大的在上

                  如果是需要降序的话--那么就是小堆---小堆就是说小的在上

3.利用堆删除的思想来进行排序

  • 记录堆尾下标end;

  • 交换堆顶(0)堆尾(end)元素——将最大值交换到序列尾。

  • 向下调整,但此时的调整范围到end——恢复堆结构选出最大值

  • –end——进行下一轮选择交换。

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆

  • 堆排序的特性总结:

    堆排序使用堆来选数,效率就高了很多。
  • 时间复杂度:O(N*logN)
  • 空间复杂度:O(1)
  • 稳定性:不稳定,由于使用了堆结构,无法保证稳定性数据
  • 敏感性:不敏感,不管有序无序都要重新建堆排序

3.归并排序

归并排序就是找到一个基准值,大的在基准值的右,小的在基准值的左边。

然后开始递归-------当只有一个元素时就不需要了,然后返回上一层,再次进行排序即可。

具体步骤如下:

  1. 正式排序前需要创建与待排数组相同大小的数组tmp。

  2. 首先计算出中间位置的下标,将序列一分为二。

  3. 如果子区间元素个数大于1则向下递归先使左右子区间有序

  4. 然后将左右子区间归并到tmp数组

  5. 最后将数据考回原数组。

代码如下:

void _MergeSort(int *arr, int left, int right, int *tmp)
{//注意递归的结束条件if (left >= right){return;}//计算出中间位置的下标int mid = left + (right - left) / 2;//划分左右区间int begin1 = left, end1 = mid;int begin2 = mid + 1, end2 = right;//先使左右两区间有序_MergeSort(arr, begin1, end1, tmp);_MergeSort(arr, begin2, end2, tmp);//将左右两区间归并到tmp数组//注意排序的区间不从0开始int i = left;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2]){tmp[i++] = arr[begin1++];}else{tmp[i++] = arr[begin2++];}}while (begin1 <= end1){tmp[i++] = arr[begin1++];}while (begin2 <= end2){tmp[i++] = arr[begin2++];}//将排好的数据从tmp数组考回arrfor (int j = left; j <= right; j++)//注意这里一定是从left-right而不是从0-sz-1//因为当递归进去之后,就不一定是0-sz-1了。也有可能是只有两个数:例 下标2-3{arr[j] = tmp[j];}
}void MergeSort(int *arr, int sz){//递归排序过程中需使用额外空间int *tmp = (int*)malloc(sizeof(int) * sz);if (tmp == NULL){perror("MergeSort");exit(1);}_MergeSort(arr, 0, sz - 1, tmp);//排序结束后记得释放额外空间free(tmp);tmp = NULL;
}

 将数组一分为二,先使数组的左右区间有序,再将左右区间归并成一个有序数组。对比快速排序,归并排序与二叉树的后序遍历思想更为相似。

归并排序解决磁盘问题:

归并排序的特点:

1. 归并排序兼具高效、稳定、数据不敏感的特点;缺点在于需要O(N)的空间。常用于外排序问题。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(N)
4. 稳定性:稳定
5. 数据敏感性:不敏感---即使是数据已经有序,也要进行排列(可以称这种排列为伪排列)。

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

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

相关文章

Centos7 搭建单机elasticsearch

以下是在 CentOS 7 上安装 Elasticsearch 7.17.7 的完整步骤&#xff1a;&#xff08;数据默认保存在/var/lib/elasticsearch下&#xff0c;自行更改&#xff09; 一、装 Java 环境 Elasticsearch 是用 Java 编写的&#xff0c;所以需要先安装 Java 运行环境。 检查系统中是…

pdf怎么删除多余不想要的页面?删除pdf多余页面的多个方法

pdf怎么删除多余不想要的页面&#xff1f;在日常办公或学习中&#xff0c;我们经常会遇到需要处理PDF文件的情况。PDF文件因其格式稳定、不易被篡改的特点而广受青睐&#xff0c;但在编辑方面却相对不如Word等文档灵活。有时&#xff0c;在接收或创建的PDF文件中&#xff0c;可…

OceanBase 的写盘与传统数据库有什么不同?

背景 在数据库开发过程中&#xff0c;“写盘”是一项核心操作&#xff0c;即将内存中暂存的数据安全地转储到磁盘上。在诸如MySQL这样的传统数据库管理系统中&#xff0c;写盘主要有以下几步&#xff1a;首先将数据写入缓存池&#xff1b;其次&#xff0c;为了确保数据的完整性…

利用Spring Boot构建大创项目资源规划平台

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

Linux的zookeeper安装部署

1.zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是hadoop和HBASE的重要组件 2.下载zookeeper安装包zookeeper安装包https://archive.apache.org/dist/zookeeper/zookeeper-3.5.9/ 移动到Linux解压 解压到/export/server文件夹 命令: tar -xvf apache-zooke…

【前端】如何制作一个自己的网页(6)

接上文 网络中的图片 我们也可以在百度等网站搜索自己喜欢的图片。 此时对图片点击右键&#xff0c;选择【复制图片地址】&#xff0c;即可获得该图片的网络地址。 其实在HTML中&#xff0c;除了图片以外&#xff0c;我们还可以利用地址找到另一个网页。 如右图所示&#…

spring/springboot获取resource目录下的文件

1.正常情况springbot项目的resource目录下会反正项目使用到的很多文件所以这里编写一个读取demo目录如下图所示 2.复制代码直接运行 import org.springframework.core.io.ClassPathResource; import java.nio.file.Files; import java.util.stream.Stream;/*** spring/spring…

第十四章 RabbitMQ延迟消息之延迟队列

目录 一、引言 二、死信队列 三、核心代码实现 四、运行效果 五、总结 一、引言 什么是延迟消息&#xff1f; 发送者发送消息时指定一个时间&#xff0c;消费者不会立刻收到消息&#xff0c;而是在指定时间后收到消息。 什么是延迟任务&#xff1f; 设置在一定时间之后才…

深入探讨C++多线程性能优化

深入探讨C多线程性能优化 在现代软件开发中&#xff0c;多线程编程已成为提升应用程序性能和响应速度的关键技术之一。尤其在C领域&#xff0c;多线程编程不仅能充分利用多核处理器的优势&#xff0c;还能显著提高计算密集型任务的效率。然而&#xff0c;多线程编程也带来了诸…

大模型微调实战指南:从零开始手把手教你微调大模型

文末有福利&#xff01; 今天分享一篇技术文章&#xff0c;你可能听说过很多大模型的知识&#xff0c;但却从未亲自使用或微调过大模型。 今天这篇文章&#xff0c;就手把手带你从零微调一个大模型。 大模型微调本身是一件非常复杂且技术难度很高的任务&#xff0c;因此本篇…

为什么在Anaconda中会报错‘chcp‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件?

首先&#xff0c;我们需要知道,这意味着chcp 命令在系统路径中找不到。chcp&#xff08;Change Code Page&#xff09;是一个Windows命令行工具&#xff0c;用于查看或设置活动控制台窗口的代码页。 经过统计整合了一些原因如下: 1.系统环境变量被错误地修改 可能导致系统命…

【closerAI ComfyUI】真人秒变卡通,相似度爆表!炫酷工作流,让你的卡通写真秒变朋友圈焦点!快来试试吧!

【closerAI ComfyUI】真人卡通化&#xff0c;超像&#xff01;这个工作流真棒&#xff01;用个人写真照片转卡通风格去轰炸你的朋友圈吧&#xff01; 这期我们主要讨论如何使用stable diffusion comfyUI 制作定制写真卡通照片工作流。也就是真人照片转卡通形象。 closerAI工作…

什么是乐观锁、悲观锁?

什么是乐观锁、悲观锁&#xff1f; 乐观锁&#xff1a;乐观锁和悲观锁是并发控制的两种方式&#xff0c;用来确保在多线程或多用户访问共享资源时&#xff0c;数据的一致性和完整性。 悲观锁&#xff08;Pessimistic Lock&#xff09; 悲观锁假设并发操作会经常发生&#xf…

【漏洞复现】SpringBlade menu/list SQL注入漏洞

》》》产品描述《《《 致远互联智能协同是一个信息窗口与工作界面,进行所有信息的分类组合和聚合推送呈现。通过面向角色化、业务化、多终端的多维信息空间设计,为不同组织提供协同门户,打破组织内信息壁垒,构建统一协同沟通的平台。 》》》漏洞描述《《《 致远互联 FE协作办公…

【PyTorch】DataLoader 设置 num_workers > 0 时,出现 CUDA with multiprocessing 相关报错

【PyTorch】DataLoader 设置 num_workers > 0 时&#xff0c;出现 CUDA with multiprocessing 相关报错 1 报错信息2 报错分析2.1 原因2.2 结论 3 解决方法 1 报错信息 RuntimeError: Caught RuntimeError in DataLoader worker process 0.RuntimeError: Cannot re-initial…

mac安装homebrew和git

简介 由于把自己的新mac拿来撸代码&#xff0c;开始环境搭建&#xff0c;安装各种工具和依赖&#xff0c;安装 git 需要先安装 homebrew&#xff0c;然后就遇到了 homebrew 安装失败的问题。 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection…

基于SpringBoot+Vue+uniapp的C语言在线评测系统的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

NewStarCTF2024-Week2-Web-WP

目录 1、复读机 2、你能在一秒内打出八句英文吗 3、遗失的拉链 4、谢谢皮蛋 plus 5、PangBai 过家家&#xff08;2&#xff09; 1、复读机 测了下存在 ssti 没什么说的 fenjing 秒了 2、你能在一秒内打出八句英文吗 每次出来的需要提交的内容都不一样 exp&#xff1a; …

如何从头训练大语言模型: A simple technical report

写在前面 自8月底训好自己的1.5B的LLM后&#xff0c;一直都没有发布一个完整的技术报告&#xff0c;不少小伙伴私信我催更&#xff0c;千呼万唤始出来。其实也没有太大动力去做&#xff0c;原因有三&#xff1a; 豁然开朗&#xff1a;搞定全流程之后&#xff0c;对LLM确实豁然…