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

news2024/11/18 11:29:38

排序算法总结

在这里插入图片描述

直接插入排序

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

//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问题大汇总在这里插入图片描述

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

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

相关文章

如何确保JDK版本与操作系统架构匹配?

1. 序言 最近的工作中&#xff0c;需要升级JDK版本到17.0.7&#xff0c;以解决一个JDK bug&#xff1a;JDK-8299626该bug的core dump关键字如下&#xff1a;SIGSEGV in PhaseIdealLoop::build_loop_late_post_work公司JDK团队提供的、包含JDK的基础镜像&#xff0c;有aarch64和…

深入了解Java虚拟机(JVM)

Java虚拟机&#xff08;JVM&#xff09;是Java程序运行的核心组件&#xff0c;它负责解释执行Java字节码&#xff0c;并在各种平台上执行。JVM的设计使得Java具有跨平台性&#xff0c;开发人员只需编写一次代码&#xff0c;就可以在任何支持Java的系统上运行。我们刚开始学习Ja…

Launch学习

参考博客&#xff1a; (1) 史上最全的launch的解析来啦&#xff0c;木有之一欧 1 ROS工作空间简介 2 元功能包 src目录下可以包含多个功能包&#xff0c;假设需要使用机器人导航模块&#xff0c;但是这个模块中包含着地图、定位、路径规划等不同的功能包&#xff0c;它们的逻…

【Python】1. 背景知识

认识 Python 计算机基础概念 什么是计算机? 很多老一辈的人, 管下面这个叫做计算机. 然鹅, 它只是 “计算器”, 和计算机是有很大区别的. 现在我们所说的计算机, 不光能进行算术运算, 还能进行逻辑判断, 数据存储, 网络通信等等功能,。 以至于可以自动的完成非常复杂的工作…

SLAM基础知识-卡尔曼滤波

前言&#xff1a; 在SLAM系统中&#xff0c;后端优化部分有两大流派。一派是基于马尔科夫性假设的滤波器方法&#xff0c;认为当前时刻的状态只与上一时刻的状态有关。另一派是非线性优化方法&#xff0c;认为当前时刻状态应该结合之前所有时刻的状态一起考虑。 卡尔曼滤波是…

java垃圾回收

垃圾回收 一个对象如果不再使用&#xff0c;需要手动释放&#xff0c;否则就会出现内存泄漏。我们称这种释放对象的过程为垃圾回收&#xff0c;而需要程序员编写代码进行回收的方式为手动回收。 内存泄漏指的是不再使用的对象在系统中未被回收&#xff0c;内存泄漏的积累可能…

LCR 124. 推理二叉树

解题思路&#xff1a; 分治 class Solution {// 一个哈希表用于存储中序遍历中每个值对应的索引&#xff0c;用于快速查找HashMap<Integer,Integer> map new HashMap<>();// 保存前序遍历的结果数组int[] preorder;// 主函数&#xff0c;传入前序和中序遍历的结果…

Vue中的计算属性和方法有什么区别?

Vue.js是一款流行的JavaScript前端框架&#xff0c;提供了丰富的功能和便捷的开发方式。在Vue中&#xff0c;计算属性和方法是常用的两种方式来处理数据和逻辑。但它们之间存在一些区别&#xff0c;本文将详细介绍Vue中计算属性和方法的区别&#xff0c;并通过示例代码加深理解…

UE4c++ ConvertActorsToStaticMesh ConvertProceduralMeshToStaticMesh

UE4c ConvertActorsToStaticMesh 创建Edior模块&#xff08;最好是放Editor模块毕竟是编辑器代码&#xff09;创建蓝图函数UBlueprintFunctionLibraryUTestFunctionLibrary.hUTestFunctionLibrary.cpp:.Build.cs 目标:为了大量生成模型&#xff0c;我们把虚幻带有的方法迁移成函…

一周学会Django5 Python Web开发-Django5详细视图DetailView

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计28条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的停车位检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;开发停车位检测系统对于优化停车资源管理和提升用户体验至关重要。本篇博客详细介绍了如何利用深度学习构建一个停车位检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并结合了YOLOv7、YOLOv6、YOLOv5的性能对比&#xf…

python-分享篇-控制摄像头

文章目录 准备代码效果 准备 安装cv2 pip install opencv-python &#xff08;如果只用主模块&#xff0c;使用这个命令安装&#xff09; pip install opencv-contrib-python &#xff08;如果需要用主模块和contrib模块&#xff0c;使用这个命令安装&#xff09; 我的代码l里…

Vue+SpringBoot打造知识图谱构建系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 知识图谱模块2.2 知识点模块2.3 学生测评模块2.4 学生成绩模块 三、系统展示四、核心代码4.1 查询知识点4.2 新增知识点4.3 查询知识图谱4.4 查询学生成绩4.5 查询学生成绩 五、免责说明 一、摘要 1.1 项目介绍 基于J…

AJAX 学习笔记(Day3)

「写在前面」 本文为黑马程序员 AJAX 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. AJAX 学习笔记&#xff08;Day1&#xff09; 目录 3 AJAX 原理 3.1 XMLHttpRequest 3…

Stable Video文本生成视频公测地址——Scaling Latent Video Diffusion Models to Large Datasets

近期&#xff0c;Stability AI发布了首个开放视频模型——"Stable Video"&#xff0c;该创新工具能够将文本和图像输入转化为生动的场景&#xff0c;将概念转换成动态影像&#xff0c;生成出电影级别的作品&#xff0c;旨在满足广泛的视频应用需求&#xff0c;包括媒…

为什么要在业务系统中引入大宽表?

在高度系统化驱动的业务中&#xff0c;查看业务报表已经是一个很常见的需求了。在分工非常明确的大型企业里&#xff0c;往往有专门的数据分析团队 BI 或者数据开发团队&#xff0c;他们能够胜任此类需求&#xff08;但也未必是轻松的&#xff0c;或者说高效的&#xff09;。 …

编码器原理图

操作 旋转编码器提供两种交互方式&#xff1a; 每次用户旋转旋钮时&#xff0c;都会在 DT 和 CLK 引脚上产生低电平信号&#xff1a; 顺时针旋转会先使CLK引脚变为低电平&#xff0c;然后DT引脚也变为低电平。 逆时针旋转会使 DT 引脚首先变为低电平&#xff0c;然后 CLK 引脚…

深度学习PyTorch 之 RNN-中文多分类

关于RNN的理论部分我们已经在前面介绍过&#xff0c;所以这里直接上代码 1、 数据部分 1.1 读取数据 # 加载数据 data_path ./data/news.csv data pd.read_csv(data_path)# 预览数据的前几行 data.head()数据是csv格式&#xff0c;只有两列&#xff0c;第一列是标签&#…

2024最新外贸建站:WordPress搭建外贸独立站零基础教程

想与外国人做生意有多种方式&#xff0c;一些朋友选择在跨境电商平台上开店如&#xff08;亚马逊&#xff09;&#xff0c;而另一些朋友则决定建立自己的外贸独立站点。本篇教程主要说的是第二种方式如何快速建立自己的外贸独立站&#xff01;通过学习这篇外贸建站教程&#xf…

【AI绘画】免费GPU Tesla A100 32G算力部署Stable Diffusion

免责声明 在阅读和实践本文提供的内容之前&#xff0c;请注意以下免责声明&#xff1a; 侵权问题: 本文提供的信息仅供学习参考&#xff0c;不用做任何商业用途&#xff0c;如造成侵权&#xff0c;请私信我&#xff0c;我会立即删除&#xff0c;作者不对读者因使用本文所述方法…