面试准备:排序算法大汇总 C++

排序算法总结

在这里插入图片描述

直接插入排序

取出未排序部分的第一个元素,与已排序的部分从后往前比较,找到合适的位置。将大于它的已排序的元素向后移动,将该元素插入到合适的位置。

//1. 直接插入排序
void InsertionSort(vector<int>& nums){
    for(int i=1;i<nums.size();i++){
        int key = nums[i];//取出未排序部分的第一个元素
        int j =i-1;
        // 将这个元素与已排序部分的元素从后向前比较,找到合适的位置插入
        while(j>=0 && nums[j]>key){
            nums[j+1]=nums[j];// 已排序的元素向后移动
            j--;
        }
        nums[j+1]=key; // 插入到正确位置
    }
}

希尔排序

希尔排序是一种基于插入排序的算法,通过引入间隔序列来允许交换距离较远的元素,从而对数组进行部分排序,这个过程重复进行,每次都减小间隔,直到整个数组被排序。

//2. 希尔排序,分组后组内进行直接插入排序
void shellSort(vector<int>& nums){
    int n = nums.size();
    //gap最初为n/2,然后不断减小直至为1
    for(int gap = n/2; gap>0 ;gap/=2){
        for(int i = gap ;i < n; i += 1){
            //获取未排序的第一个元素
            int key = nums[i];
            int j=i-gap;
            //前一个元素是i-gap;
            while(j>=0 && nums[j]>key){
                nums[j+gap]=nums[j];
                j-=gap;
            }
            nums[j+gap]=key;
        }
    }
}

冒泡排序

冒泡排序的核心思想是通过重复遍历要排序的列表,比较每对相邻的项,然后交换它们(如果它们是在错误的顺序)。这个过程重复进行,直到没有需要交换的项,这意味着列表已经排序完成。每完成一轮遍历,至少一个元素会被移动到其最终位置。

//3. 冒泡排序
void bubbleSort(vector<int>& nums){
    int n = nums.size();
    for(int i=0;i<n-1;i++){   
        bool flag = false;
        for(int j=0;j<n-i-1;j++){
            if(nums[j]>nums[j+1])
                swap(nums[j],nums[j+1]);
            flag = true;
        }
        if(flag==false) return; //如果这一趟没有发生任何交换,则意味已经有序。
    }
}

快速排序

快速排序是一种高效的排序算法,采用分治法的思想来对数组进行排序。它的基本步骤是选择一个元素作为基准(pivot),重新排列数组,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准的后面(相等的数可以到任一边)。在这个分区退出之后,该基准就处于数组的中间位置。这个过程称为分区(partition)操作。然后,递归地(recursive)把小于基准值元素的子数组和大于基准值元素的子数组排序。

//4. 快速排序
int partition(vector<int>& nums,int low, int high)
{
    int pivot=nums[low];
    int i=low;
    int j=high;
    while(i<j){
        // 从右向左找到第一个小于等于pivot的数   
        while(i<j && nums[j]>pivot){
            j--;
        }
        if(i<j){
            nums[i]=nums[j];
            i++;
        }
        // 从左向右找到第一个大于pivot的数
        while(i<j && nums[i]<pivot){
            i++;
        }
        if(i<j){
            nums[j]=nums[i];
            j--;
        }
    }
    nums[i]=pivot;// 将基准值放到正确的位置
    return i; // 返回基准值的位置
}

void quickSort(vector<int>& nums, int low, int high){
    if(low<high){
        // pi是partitioning index,arr[pi]现在在正确的位置
        int pi = partition(nums,low,high);// 分区操作,并返回基准值的索引
        quickSort(nums,low,pi-1);//对左子树进行快速排序
        quickSort(nums,pi+1,high);//对右子树进行快速排序
    }
        
}

简单选择排序

简单选择排序是一种直观且基础的排序算法。它的工作原理是:遍历数组,每次从未排序的部分选出最小(或最大)的元素,放到已排序部分的末尾。这个过程重复进行,直到整个数组排序完成。简单选择排序的时间复杂度为O(n^2),在任何情况下都是这样,这使得它在处理大数据集时不够高效。然而,由于其实现简单,它在数据量不大时仍然是一个不错的选择。

// 5. 简单选择排序:找到最小的元素后,和第一个元素交换
void simpleSort(vector<int>& nums)
{
    for(int i=0;i<nums.size();i++){
        // 寻找[i, n)区间里的最小值的索引
        int minindex=i;
        for(int j=0;i<nums.size();j++)
        {
            if(nums[j]<nums[minindex]){
                minindex=j;
            }
        }
        swap(nums[i],nums[minindex]);
    }
}

堆排序

小根堆的时候是降序排列,大根堆是升序排列。

// 调整根堆,i是要调整的节点索引,n是堆的大小
void heapify(vector<int>& nums, int n, int i) {
    int smallest = i; // 初始化最小元素为当前节点
    int left = 2 * i + 1; // 左子节点
    int right = 2 * i + 2; // 右子节点

    // 如果左子节点更小,则更新最小元素的索引
    if (left < n && nums[left] < nums[smallest]) {
        smallest = left;
    }
    // 如果右子节点更小,则更新最小元素的索引
    if (right < n && nums[right] < nums[smallest]) {
        smallest = right;
    }
    // 如果最小元素不是当前节点,交换它们,并对交换后的节点进行调整
    if (smallest != i) {
        swap(nums[i], nums[smallest]);
        heapify(nums, n, smallest);
    }
}

// 堆排序
void heapSort(vector<int>& nums) {
    int n = nums.size();
    //构建小根堆(从最后一个非叶子节点往上,最后一个非叶子节点是n/2-1)
    for(int i = n/2-1;i>=0;i--)
    {
        heapify(nums,n,i);
    }
    //一个个从小根堆中取出,然后调整堆
    for(int i=n-1;i>0;i--){
        swap(nums[0],nums[i]);
        heapify(nums,i,0);
    }
}

归并排序

// 7. 归并排序
// 归并两个子数组的函数
// 第一个子数组是 arr[l..m]
// 第二个子数组是 arr[m+1..r]
// 归并排序是一种高效的排序算法,采用分治法的一个应用。
// 它将数组分成两半,对每部分递归地应用归并排序,
// 然后将两部分合并成一个有序数组。
// 这个过程包括分解数组成为越来越小的部分,
// 直至每个小部分只有一个元素,然后开始合并这些小部分,
// 使之有序,最终得到完全排序的数组。
void merge(vector<int>& nums,int l,int m,int r){
    int i,j,k;
    int n1=m-l+1;//左边的大小
    int n2=r-m;//右边的大小
    // 创建临时数组
    vector<int> L(n1),R(n2);
    // 拷贝数据到临时数组L R
    for(int i=0;i<n1;i++)
        L[i]=nums[l+i];
    for (j = 0; j < n2; j++)
        R[j] = nums[m + 1 + j];
    
    //归并临时数组到nums[l-r]
    i=0;
    j=0;
    k=l;
    while(i<n1 && j<n2){
        if (L[i] <= R[j]) {
            nums[k] = L[i];
            i++;
        } else {
            nums[k] = R[j];
            j++;
        }
        k++;
    }
    // 拷贝 L[] 的剩余元素
    while (i < n1) {
        nums[k] = L[i];
        i++;
        k++;
    }

    // 拷贝 R[] 的剩余元素
    while (j < n2) {
        nums[k] = R[j];
        j++;
        k++;
    }

}
void mergeSort(vector<int>& nums, int l, int r)
{   
    if(l<r){
        int m=l+(r-l)/2;

        //分别对左右办部分进行排序
        mergeSort(nums,l,m);
        mergeSort(nums,m+1,r);

        //合并这两个部分
        merge(nums,l,m,r);

    }

}

reference

https://leetcode.cn/circle/discuss/rzsN73/ 排序算法大汇总
https://mp.weixin.qq.com/s/FFsvWXiaZK96PtUg-mmtEw TOPk问题大汇总在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

#WEB前端(HTML属性)

1.实验&#xff1a;a,img 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; a: href插入超链接 默认情况下在本窗口打开链接, target可以设置打开的窗口,parent在父窗口打开&#xff0c;blank新开串口打开,top在顶层串口打开,self为默认在本窗口打开 img: 插入图片 可以插…

走进SQL审计视图——《OceanBase诊断系列》之二

1. 前言 在SQL性能诊断上&#xff0c;OceanBase有一个非常实用的功能 —— SQL审计视图(gv$sql_audit)。在OceanBase 4.0.0及更高版本中&#xff0c;该功能是 gv$ob_sql_audit。它可以使开发和运维人员更方便地排查在OceanBase上运行过的任意一条SQL&#xff0c;无论这些SQL是成…

基于 Amazon EKS 的 Stable Diffusion ComfyUI 部署方案

01 背景介绍 Stable Diffusion 作为当下最流行的开源 AI 图像生成模型在游戏行业有着广泛的应用实践&#xff0c;无论是 ToC 面向玩家的游戏社区场景&#xff0c;还是 ToB 面向游戏工作室的美术制作场景&#xff0c;都可以发挥很大的价值&#xff0c;如何更好地使用 Stable Dif…

Day10:基础入门-HTTP数据包Postman构造请求方法请求头修改状态码判断

目录 数据-方法&头部&状态码 案例-文件探针 案例-登录爆破 工具-Postman自构造使用 思维导图 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗透命令&#xff1a;文件…

数字图像处理 SUJOY滤波器:用于图像边缘检测的通用一阶导数滤波器

1、前言 因为是比较旧的论文,但是据论文作者说SUJOY滤波器为图像边缘检测提供了比其他常用的一阶导数方法(如 Robert 算子、Prewitt 算子、Sobel 算子等)更好的方法。 经过测试感觉并没有作者说的那么好,很水的东西,另外图像领域的事情很少有绝对的,通常都是某些方法适合…

【二分】第k个缺失的数

第K个缺失的数 链接 . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/kth-missing-positive-number/ 题目 题解 二段…

医学大数据|文献阅读|有关“胃癌+机器学习”的研究记录

目录 1.基于32基因特征构建的机器学习模型可有效预测胃癌患者的预后和治疗反应 2.胃癌患者术后90天死亡率的机器学习风险预测模型 3.使用机器学习模型预测幽门螺杆菌根除患者胃癌患病风险 4.利用初始内窥镜检查和组织学结果进行个性化胃癌发病率预测 1.基于32基因特征构建的…

ABAP - SALV教程07 斑马纹显示和SALV标题

SALV设置斑马纹和标题 METHOD set_layout.DATA: lo_display TYPE REF TO cl_salv_display_settings. * 取得显示对象lo_display co_alv->get_display_settings( ).* 设置ZEBRA显示lo_display->set_striped_pattern( X ). * 设置Titlelo_display->set_list_he…

探讨倒排索引Elasticsearch面试与实战:从理论到实践

在当前大数据时代&#xff0c;Elasticsearch&#xff08;以下简称为ES&#xff09;作为一种强大的搜索和分析引擎&#xff0c;受到了越来越多企业的青睐。因此&#xff0c;对于工程师来说&#xff0c;掌握ES的面试准备和实战经验成为了必备技能之一。本文将从ES的面试准备和实际…

【MCAL】TC397+EB-tresos之CAN配置实战 - (CAN/CANFD)

本篇文章介绍了在TC397平台使用EB-tresos对CAN驱动模块进行配置的实战过程,不仅介绍了标准CAN的发送与接收&#xff0c;还介绍了CANFD的实现与调试以及扩展帧的使用。M_CAN是德国博世公司开发的IP&#xff0c;因为英飞凌的芯片完整的集成了这个IP&#xff0c;所以整体的配置都比…

leetcode 热题 100_三数之和

题解一&#xff1a; 双指针遍历&#xff1a;暴力解法的三层遍历会超时&#xff0c;因此需要优化遍历的过程。首先是需要对结果进行去重&#xff0c;这里采用排序跳过重复值的做法&#xff0c;在指针遍历时跳过已经遍历过的相同值。在第一层循环确定第一个值后&#xff0c;剩下两…

【RT-Thread基础教程】邮箱的使用

文章目录 前言一、邮箱的特性二、邮箱操作函数2.1 创建邮箱创建动态邮箱创建静态邮箱 2.2 删除邮箱2.3 发邮件2.4 取邮件 三、示例代码总结 前言 RT-Thread是一个开源的实时嵌入式操作系统&#xff0c;广泛应用于各种嵌入式系统和物联网设备。在RT-Thread中&#xff0c;邮箱是…

阶跃信号与冲击信号

奇异信号&#xff1a;信号与系统分析中&#xff0c;经常遇到函数本身有不连续点&#xff08;跳变电&#xff09;或其导函数与积分有不连续点的情况&#xff0c;这类函数称为奇异函数或奇异信号&#xff0c;也称之为突变信号。以下为一些常见奇异函数。 奇异信号 单位斜变信号 …

java-ssm-jsp-宠物护理预定系统

java-ssm-jsp-宠物护理预定系统 获取源码——》公主号&#xff1a;计算机专业毕设大全

xxl-job--01--简介

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.xxl-job1. 1 发展历史1.2 XXL-JOB的系统架构1.3 xxl-job与其他框架对比 2. XXL-JOB的使用2.1 准备工作- 配置调度中心XXL-JOB的数据表 2.2 配置执行器1 引入依赖包…

一个脚本两步计算材料Raman谱(附数据处理和绘图脚本)

在以往推送中已经介绍了相当多的计算材料Raman的方法&#xff0c;使用的软件主要为Phonopy-Spectroscopy&#xff0c;相关软件还有vasp&#xff0c;phonopy&#xff0c;phono3py等。 Phonopy-Spectroscopy计算材料红外和Raman光谱 Phonopy-Spectroscopy 计算红外和拉曼光谱 也…

Github配置SSH免密认证

以Ubuntu Server为例 生成SSH ssh-keygen -t ed25519 -C "your_emailexample.com" 如果系统不支持Ed25519算法&#xff0c;使用旧的命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 根据提示生成公私钥文件&#xff0c;记下位置…

深度学习_17_丢弃法调整过拟合

除了权重衰退法调整过拟合&#xff0c;还有丢弃法调整模型得过拟合现象 过拟合&#xff1a; 丢弃法如果直接丢弃会导致新期望的不确定性&#xff0c;为了防止这个不确定被模型学到&#xff0c;所以要保证丢弃后的期望和丢弃前的期望一样&#xff08;个人观点&#xff09; 顾…

微服务笔记

什么是微服务? 微服务是一种经过良好架构设计的分布式架构方案&#xff0c;微服务架构特征: 1.单一职责:微服务拆分粒度更小&#xff0c;每一个服务都对应唯一的业务能力&#xff0c;做到单一职责&#xff0c;避免重复业发。 2.面向服务:微服务对外暴露业务接口 3.自治:团…

基于Springboot的人事管理系统 (有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的人事管理系统 &#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&am…