十大排序 C++代码

2023-05-16

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;
const int N = 1e5+10;
int nums[N], help[N];
int n;

//快速排序 - l,j 有序 j+1, r 中 j左边的数都小于等于nums[j]右边的都大于等于nums[j]
void quickSort(int l, int r){
    if(l >= r)  return;
    int x = nums[l+r>>1], i = l-1, j = r+1;
    while(i < j){
        do i++; while(x > nums[i]);
        do j--; while(x < nums[j]);
        if(i < j)
            swap(nums[i], nums[j]);
    }
    quickSort(l, j), quickSort(j+1, r);
}

//选择排序 - 每轮都选择剩余元素中 最小的 和 第一个 进行交换
void selectSort() { 
    
    for(int i = 0; i < n-1; ++i) {
        int cur_min = i;
        for(int j = i+1; j < n; ++j) {
            if(nums[j] < nums[cur_min]) {
                cur_min = j;
            }
        }
        swap(nums[i], nums[cur_min]);
    }
}

//插入排序 - 待序元素插入有序元素 因此需要在搜索位置的同时 后移有序元素
void insertSort() {
    //从i开始是默认i == 0已经是有序    
    for(int i = 1; i < n; ++i) {
        auto value = nums[i];//必须备份 因为会覆盖
        int j = i-1;
        while(j >= 0 && nums[j] > value) {
            nums[j+1] = nums[j];
            --j;
        }
        nums[j+1] = value;
    }
}

//冒泡排序 - 实际上是每轮就确定一个最大的元素(如果按照从小到大排列)
void bubbleSort() {
    for(int i = 0; i < n-1; ++i) {
        bool flag = false;//这样写在最佳情况下的时间复杂度才会是O(n)
        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)   break;
    }
}

//归并排序 - 分治思想,左右数组都是排好序的 然后再合并、统一排序
void mergeSort(int l, int r) {
    if(l >= r)  return ;
    int mid = l+r>>1;
    int i = l, j = mid+1, cnts = 0;
    mergeSort(l, mid), mergeSort(mid+1, r);
    while(i <= mid && j <= r) {
        help[cnts++] = nums[i] <= nums[j] ? nums[i++] : nums[j++];
    }
    while(i <= mid) help[cnts++] = nums[i++];
    while(j <= r)   help[cnts++] = nums[j++];
    
    for(int i = 0; i < cnts; ++i) {
        nums[l++] = help[i];
    }
}

//计数排序 - 适合数据比较集中的排序,将元素转换成键值
void countSort() {
    auto max_value = *max_element(nums, nums+n);
    auto min_value = *min_element(nums, nums+n);
    vector<int> count(max_value - min_value + 1);
    
    for(int i = 0; i < n; ++i) {
        ++count[nums[i]-min_value];
    }
    
    /*这样写就结束的话 无法保证数据的稳定性 因为覆盖原数组
    int indx = 0;
    for(int i = 0; i < count.size(); ++i) {
        for(int j = 0; j < count[i]; ++j) {
            nums[indx++] = i + min_value;
        }
    }
    */
    
    //因此 -> 从后面 反向填充数组:相等的先填充后面的,然后减少计数值
    for(int i = 1; i < count.size(); ++i) {
        count[i] = count[i-1] + count[i];
    }
    
    
    int res[n];
    for(int i = n-1; i >= 0; --i) {
        auto cnts = count[nums[i]-min_value];
        res[cnts-1] = nums[i];
        --count[nums[i]-min_value];
    }
    memcpy(nums, res, sizeof res);
}

//基数排序 - 适合给位数较多的数字进行排序 (几进制的数字就只需要准备几个桶)
void radixSort() {
    auto max_value = *max_element(nums, nums+n);
    int bit = 0, tmp = max_value;
    while(tmp) {
        tmp /= 10;
        ++bit;
    }
    int radix = 1;
    vector<int> count(10);
    int res[n];
    
    for(int i = 1; i <= bit; ++i) {
        memset(res, 0, sizeof res);
        
        for(int j = 0; j < n; ++j) {
            ++count[nums[j]/radix%10];
        }
        
        for(int j = 1; j < 10; ++j) {
            count[j] = count[j-1] + count[j];
        }
        
        
        int indx = 0;
        for(int j = n-1; j >= 0; --j) {
            int cnts = count[nums[j]/radix%10];
            res[cnts-1] = nums[j];
            --count[nums[j]/radix%10];
        }
        memcpy(nums, res, sizeof res);
        
        radix *= 10;
    }
}

//桶排序 - 每个桶内部排序后再统一排序
void bucketSort() {
    int k = 10;
    auto max_value = *max_element(nums, nums+n);
    auto min_value = *min_element(nums, nums+n);
    int bucket_num = (max_value - min_value) / k + 1;
    vector<int> bucket[bucket_num];
    
    for(int i = 0; i < n; ++i)  bucket[(nums[i]-min_value)/k].emplace_back(nums[i]);
    
    for(int i = 0; i < bucket_num; ++i) sort(bucket[i].begin(), bucket[i].end());
    
    int indx = 0;
    for(int i = 0, j = 0; i < bucket_num; ) {
        if(j < bucket[i].size())    nums[indx++] = bucket[i][j++];
        else    i++, j = 0;
    }
    
}

//堆排序 - 和别的不一样 小标从1开始方便维护,每次都维护堆,将维护完成的放到数组末尾
void down(int u, int sz) {
    int tmp = u;
    while(2*u <= sz && nums[2*u] < nums[tmp])   tmp = 2*u;
    while(2*u+1 <= sz && nums[2*u+1] < nums[tmp])   tmp = 2*u+1;
    if(tmp != u) {
        swap(nums[tmp], nums[u]);
        down(tmp, sz);
    }
}
void up(int u) {
    while(u/2 && nums[u/2] > nums[u]) {
        swap(nums[u/2], nums[u]);
        u /= 2;
    }
}
void heapSort() {
    //建堆
    for(int i = n/2; i; --i)   down(i, n);

    for(int i = n; i > 1; --i) {
        swap(nums[1], nums[i]);
        down(1, i-1);
    }
}

//希尔排序 - 在插入排序一步步移动的基础上优化步长
void shellSort() {
    
    for(int gap = n/2; gap; gap /= 2) {
        for(int i = gap; i < n; ++i) {
            int tmp = nums[i], j = i;
            for( ; j >= gap && tmp < nums[j-gap]; j -= gap) {
                nums[j] = nums[j-gap];
            }
            nums[j] = tmp;
        }
    }
}
int main(){
    cin >> n;
    for(int i = 0; i < n; ++i)  cin >> nums[i];
    //quickSort(0, n-1);
    //selectSort();
    //insertSort();
    //bubbleSort();
    //mergeSort(0, n-1);
    //countSort();
    //radixSort();
    bucketSort();
    //heapSort();
    //shellSort();

    for(int i = 0; i < n; ++i)  cout << nums[i] << " ";
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

十大排序 C++代码 的相关文章

  • Linux 基本用户和组命令

    Linux 基本用户和组命令 1有关用户的命令 1 新增用户 Useradd 43 用户名 2 查看用户是否存在 id 43 用户名 3 删除用户 sudo userdel 用户名 只会删除用户本身 sudo userdel r 43 用户
  • Linux文件及权限

    Linux文件及权限 1 xff0e 查看文件权限 1 ls l 命令 ll 命令 显示详细信息 例 xff1a root 64 localhost Desktop ll total 178752 rwxr xr x 1 root root
  • 各种排序算法和应用场景

    简介 插入排序 插入排序是一种较为简单的排序算法 xff0c 它的基本思想是通过构建有序序列 xff0c 对于未排序数据 xff0c 在已排序序列中从后向前扫描 xff0c 找到相应位置并插入 形象的可以理解为打扑克抓拍的过程 xff0c
  • C/C++(3)C++调用C语言的函数和头文件

    C 43 43 语言支持函数重载 xff0c C语言不支持函数重载 函数被C 43 43 编译后在库中的名字与C语言的不同 xff0c C xff0b xff0b 和C是两种完全不同的编译链接处理方式 xff0c 如果直接在C xff0b
  • 一文了解IMU原理、误差模型、标定、惯性传感器选型以及IMU产品调研(含IMU、AHRS、VRU和INS区别)

    在此记录一下测试IMU过程中的其它文章 xff0c 便于以后查看 xff1a IMU的误差标定以及姿态解算ROS下通过USB端口读取摄像头数据 包括笔记本自带摄像头 激光 摄像头 IMU等传感器数据同步方法 message filters
  • windows安装Ubuntu子系统以及图形化界面记录

    文章目录 1 windows环境设置2 开始安装3 ubuntu使用3 1 启动和退出 Linux 子系统3 2 安装位置3 3 更换源 4 安装图形化界面4 1 安装VcXsrv4 2 安装桌面环境 xff08 1 xff09 方法1 x
  • STM32 DMA正常模式等待传输完成和开始下一次传输

    选择DMA的正常模式 xff0c 即DMA只传输一次 如果当传输完一次后 xff0c 还想再传输一次 xff0c 就需要重启DMA xff1a DMA Cmd DMA1 Channel6 DISABLE 重新设置源地址 重新设置目的地址 重
  • 增量式编码器和绝对式编码器,ABI信号和UVW信号、编码器PWM信号

    一 编码器的分类 根据检测原理 xff0c 编码器可分为光学式 磁式 感应式和电容式 xff0c 根据其刻度方法及信号输出形式 xff0c 可分为增量式 绝对式以及混合式三种 1 增量式编码器 增量式编码器是直接利用光电转换原理输出三组方波
  • 路由器接口管理 控制端口 辅助端口 物理端口 逻辑端口 局域网

    路由器接口管理 路由器的接口相对于交换机来说最大的特点就是接口类型和配置更为复杂 xff0c 一般吧路由器上的接口分为三大类 xff1a 1 局域网的LAN接口 xff0c 2 用于广域网接入 互联的WAN接口 xff0c 3 应用于LAN
  • C++各大有名库的介绍

    C 43 43 各大有名库的介绍 在C 43 43 中 xff0c 库的地位是非常高的 C 43 43 之父 Bjarne Stroustrup先生多次表示了设计库来扩充功能要好过设计更多的语法的言论 现实中 xff0c C 43 43 的
  • 树莓派搭建nas服务器的详细过程

    前奏 默认的登录帐号为 pi xff0c 密码是 raspberry 开启 ssh 在根目录 xff0c 新建一个名为 ssh 的空白文件就行了 然后 xff0c 重启就可以ssh访问了 命令行下配置 xff1a sudo raspi co
  • buffer overflow detected错误

    最近在写并行程序的时候遇到这个问题 在上网查询之后发现好多是由于sprintf的缓冲区不够造成的 对比自己程序发现一个很低级的错误 char sc 61 new char 100 sprintf sc 34 d 34 rank string
  • 聊一聊关于ROS开发常用的调试工具(rostopic,rosnode等等)

    ROS常用的调试工具有rosnode xff0c rostopic 1 rosnode 参数用法作用listrosnode list查看当前运行了哪些节点inforosnode info node name查看该节点发布 接受哪些话题以及服
  • 关于SLAM-Hector建图方法的一些基础点

    hector建图算法 1 简介 hector slam不需要里程计数据 xff0c 使用高斯牛顿方法 xff0c 直接使用激光雷达数据估算里程计信息 所以 xff0c 只需要激光雷达数据 xff0c 即可完成建图 2 优缺点 优点 xff1
  • 查全率(Recall)、查准率(Precision)以及综合评价指标(F1-Measure )

    xfeff xfeff 原文转载于 xff1a http www cnblogs com bluepoint2009 archive 2012 09 18 precision recall f measures html 在信息检索和自然语
  • 什么是码,主码,主属性,非主属性

    xfeff xfeff 码 xff1a 代表数目的符号 主码 我们在建立数据库的时候 xff0c 需要为每张表指定一个主码 xff0c 主码也叫主键 所谓主码就是在实体集中区分不同实体的候选码 一个实体集中只能有一个主码 xff0c 但可以
  • 整数二进制补码的数学原理(two's complement)

    转载自 整数二进制补码的数学原理 two 39 s complement 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • IP,子网掩码,默认网关和DNS都是什么,有什么用

    彻底明白IP 地址 完整版 xff08 含CIDR 讲解 xff09 不管是学习网络还是上网 xff0c IP 地址都是出现频率非常高的词 Windows 系统中设置IP 地址的界面如图1 所示 xff0c 图中出现了IP 地址 子网掩码
  • 催经的方法【吐血整理】

    xfeff xfeff 催经的方法 吐血整理 1 生姜红糖茶 2 益母草颗粒 xff0c 中成药 xff0c 很有效 3 乌鸡白凤丸 43 逍遥丸 艾灸 至少对我这个寒性体质导致的姨妈不来很有效 一周不到姨妈必来 4 把药膏贴在肚脐眼 气血
  • 向量的模和范数

    xfeff xfeff 向量的模 向量 的 大小 或长度 xff09 叫做向量的模 xff0c 记作 平面向量 61 x y xff0c 模长是 xff1a 空间向量 61 x y z xff0c 模长是 xff1a 对于向量 属于 n 维

随机推荐

  • 基于LMS的正弦信号去噪

    coding utf 8 34 34 34 Created on Thu May 30 21 17 42 2013 64 author Timchen525 34 34 34 import numpy as np import matplo
  • 查找本机 CD-Key 的方法

    背景 由于笔记本的硬盘快满了 xff0c 打算换个新硬盘并重装 windows系统还希望继续使用原来的正版CD Key 方法 1 powershell 搜索 powershell xff0c 以管理员身份运行 2 查找ProductKey
  • libSVM简介及核函数模型选择

    xfeff xfeff 转自 xff1a libSVM简介及核函数模型选择 1 libSVM简介 训练模型的结构体 struct svm problem 储存参加计算的所有样本 int l 记录样本总数 double y 指向样本类别的组数
  • opencv学习系列教程之一 整体框架

    现在就业人数最多的是计算机专业 xff0c 而这个专业的很多人都是做深度学习 xff0c 或者行为识别这块 xff0c 这讲主要介绍一下很常用的一个工具 opencv 很多人说 xff0c 这是一个程序 xff0c 有些人这是很多算法 xf
  • C/C++ Socket UDP 广播消息的发送与接收

    C C 43 43 Socket UDP 广播消息的发送与接收 局域网内全网段广播消息的IP地址为 xff1a 255 255 255 255 xff0c 向该IP地址发送广播消息 xff0c 局域网下的任何网段的客户机都能收到广播 对于发
  • A* 寻路算法

    A 寻路算法 原文地址 xff1a http www gamedev net reference articles article2003 asp 概述 虽然掌握了 A 算法的人认为它容易 xff0c 但是对于初学者来说 xff0c A 算
  • 防止头文件被重复引用

    一 下划线 属于编程风格的内容 xff0c 对程序没有影响 不用下划线也可以 xff0c 用几个下划线也由个人习惯 二 其实质是一个宏名 由此我们可以防止发生重复定义或声明 假设你的头文件名为head h xff0c 根据习惯 xff0c
  • UDP通信绑定指定IP

    由于测试需要 xff0c 自己用vconfig在自己的虚拟机里添加了很多ip xff0c 实现不同Ip间的通信 UDP客户端向服务器发送报文时 xff0c 绑定会有最近IP原则 xff0c 比如 xff0c 你机器上有如下几个IP xff1
  • C++中两个同名头文件的引用顺序

    明人不说暗话 xff0c 直接上代码 xff1a 这里有两个路径下的同名head h头文件 includea head h define A 100 int funA return A includeb head h define A 20
  • 用户态协议栈学习,DKDK基本用法介绍

    网络数据流 xff0c 先了解一下用户态协议栈在什么位置 这里以DPDK为例 xff1a xff08 目的是为了获得原始的网络数据 xff0c 除了DPDK xff0c socket raw xff0c netmap也能获取获取以太网数据
  • 多旋翼基本组成

    一 总体认识 多旋翼三大系统 机身 动力系统 控制系统 xff08 导航模块 控制模块 决策模块 xff09 二 机身主体 xff1a 机架 xff08 1 xff09 作用 多旋翼的承载平台 xff0c 所有设备都是用机架承载 因此 xf
  • 数据处理(伪)代码:卡尔曼滤波 vs. 卡尔曼平滑

    步骤一 导入csv或txt格式的试验数据 最简洁也是据说读取速度最快的方法是 xff1a pPath span class token operator 61 span span class token string 39 C data o
  • 四旋翼初次组装

    一 四旋翼配置清单 初次尝试组装四旋翼 xff0c 在淘宝上买相关配件 xff0c 进行组装 初次组装 xff0c 比较乱 二 装机步骤 1 xff1a 机臂与上层中心板安装 xff0c 2 5mm螺丝 2 xff1a 香蕉头灌锡 xff0
  • 四轴飞行前检查及解锁

    一 飞行前的检查及注意事项 1 飞控的校正遥控器中 xff0c 每个通道与MP中显示的通道校正条是否一致 xff0c 遥控器控制杆摇动的方向是否正确 2 飞控的校正是否已经完成了全部校正 3 电机的的安装序号是否与飞控OUTPUT的通道数一
  • pixhawk之NSH调试

    一 ardupilot固件 windows环境 前期准备 1 xff1a pix烧录程序 xff0c Arducopter或者library中的example都可以实现 2 xff1a 拔掉SD卡 xff08 脚本中提到的没有SD卡进入ns
  • 目标检测(yolov3)实现---darknet的C语言版本

    环境安装 ubuntu opencv cuda cudnn gt920m 参考 https blog csdn net qq 36362060 article details 80739573 darknet github地址 https
  • C++PrimerPlus学习笔记——第9章内存模型和名称空间(最全最详细)

    注 xff1a 这一章都是理解记忆性的内容 xff0c 因此笔者在某些知识点会将自己的理解话语写上 xff0c 便于可读性和方便理解 本章内容包括 xff1a 单独编译 xff1b 存储持续性 作用域和链接性 xff1b 定位 xff08
  • 图论——拓扑排序及最短路径算法模板

    一 拓扑排序 span class token comment 将入度为0的点写入myQueue span vector span class token operator lt span span class token keyword
  • 2022 PAT 甲级秋 100分

    PAT2022秋 有一题是卡着时间复杂度去做的结果AC了 希望大家也能来一起交流下最优解 踩气球 AC 这道题调试了很久 才开始用的哈希表内存太大了 span class token macro property span class to
  • 十大排序 C++代码

    span class token macro property span class token directive hash span span class token directive keyword include span spa