当前位置: 首页 > 编程日记 > 正文

C++排序算法实现(更新中)

比较排序法:如冒泡排序、简单选择排序、合并排序、快速排序。其最优的时间复杂度为O(nlogn)。
其他排序法:如桶排序、基数排序等。时间复杂度可以达到O(n)。但试用范围有要求。

桶排序:排序的数组元素跨距不能很大。因为跨距很大的话,会开辟大量的内存。
基数排序:只适用于整数。

在这里插入图片描述
图片来自博客:
https://www.cnblogs.com/wuxiangli/p/6399266.html

排序的稳定性

考察排序算法的时候有一个很重要的特性,就是算法的稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

1、冒泡排序(O(n2))

1.1、普通冒泡排序

依次将最小的数冒泡到第一位。流程如下图所示。
在这里插入图片描述

void print_array(int* a)
{for(int i = 0;i<8;i++)cout<<a[i]<<"  ";cout<<endl;
}
int main()
{int a[8] = {10,23,56,12,12,0,2,15};for(int i = 0;i<8;i++){for (int j = 7; j > i; j--){if(a[j] < a[j-1]){int temp = a[j];a[j] = a[j-1];a[j-1] = temp;}}print_array(a);}
}

1.2、带标记为的冒泡排序

如果在某次冒泡的过程中,没有发生数据交换,说明已经排好序了,没有必要继续进行。因此可以设置一个标志位:bool flag。

void print_array(int* a)
{for(int i = 0;i<8;i++)cout<<a[i]<<"  ";cout<<endl;
}
int main()
{int a[8] = {10,23,56,12,12,0,2,15};bool flag = true;for(int i = 0;i<8 && flag;i++){// 如果以后没有数据交换,flag就会是falseflag = false;for (int j = 7; j > i; j--){if(a[j] < a[j-1]){// 发生数据交换时,标志位置为true。flag = true;int temp = a[j];a[j] = a[j-1];a[j-1] = temp;}}print_array(a);}
}

2、简单选择排序(O(n2))

从第一位开始,每次选择最小的数据,和开始时的数据进行交换。

void print_array(int* a)
{for(int i = 0;i<8;i++)cout<<a[i]<<"  ";cout<<endl;
}
int main()
{int a[8] = {10,23,56,12,12,0,2,15};for(int i = 0;i<7;i++){int min = i;for(int j = i+1;j<8;j++){if(a[j] < a[min])min = j;}if(min != i){int temp = a[min];a[min] = a[i];a[i] = temp;}}print_array(a);
}

3、归并排序(nlogn)

归并排序的思路为:将数组不断的分为两部分。如一个长度为8的数组—>长度为4—>长度为2—>长度为1。然后再两两合并。在合并的过程中,数组已经有序了,因此时间复杂度会降低。
在这里插入图片描述

// 合并两个数组的函数
void Merge(int* a,int left1,int right1,int left2,int right2)
{// 由于后面会用到left1,left2的原值,因此这里先备份一个。int temp_left1 = left1;int temp_left2 = left2;int n = (right1 - left1 + 1) + (right2 - left2 + 1);vector<int> result;// 此时两个数组已经是有序的,合并的过程中,有一个数组到头后就停止while(left1 <= right1 && left2 <= right2){if(a[left1] <= a[left2])result.push_back(a[left1++]);elseresult.push_back(a[left2++]);}// 遍历剩下的部分while(left1 <= right1)result.push_back(a[left1++]);while(left2 <= right2)result.push_back(a[left2++]);// 放到数组a对应的部分for(int i = 0;i<n;i++){a[temp_left1 + i] = result[i];}}
void Msort(int* a,int left,int right)
{if(left >= right) return;int medium = (left + right) / 2;// 分Msort(a,left,medium);Msort(a,medium+1,right);// 合Merge(a,left,medium,medium+1,right);
}
int main()
{int a[8] = {1,2,54,64,125,94,64,132};Msort(a,0,7);for(int i = 0;i<8;i++){cout<<a[i]<<"  ";}
}

4、快速排序(nlogn)

其思想为选一个数字,将小于该数字的值放在左边,将大于该数字的值放在右边。再将该数字的左右两侧的数组重复该过程。

思路由一篇博文提供,建议阅读以下,比我写的详细很多。链接如下:
https://blog.csdn.net/qq_28584889/article/details/88136498
在这里插入图片描述

// 第一个数大小记为temp。将小于temp的放在左边,将大于temp的放在右边
// 返回排序后temp在数组中的位置。
int partition(int* a,int left,int right)
{int temp = a[left];int i = left,j = right;while(i < j){while(a[j] >= temp && i < j)j--;while(a[i] <= temp && i < j)i++;if(i < j){int nums = a[i];a[i] = a[j];a[j] = nums;}}a[left] = a[i];a[i] = temp;return i;
}
void quickSort(int* a,int left,int right)
{if(left >= right) return;// pos为排序后,第一个数字在数组中的位置// 如:数组为4 2 1 9 6 5 8 7// partition后变为1 2 4 9 6 5 8 7// 则pos为4的位置:2int pos = partition(a,left,right);// 对左边排序quickSort(a,left,pos-1);// 对右边排序quickSort(a,pos+1,right);
}
int main()
{int a[9] = {2,6,5,9,8,4,1,3,7};quickSort(a,0,8);for(int i = 0;i<9;i++)cout<<a[i]<<"  ";
}

桶排序(O(n))

参考的一下博客,读者可自行阅读。
(1)https://blog.csdn.net/bqw18744018044/article/details/81738883?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control
(2)https://www.bilibili.com/video/av17940595?from=search&seid=4032616244052566693

void bucket_sort(double* a)
{vector<double> bucket[10];for(int i = 0;i<10;i++){int bi = 10 * a[i];bucket[bi].push_back(a[i]);}int pos = 0;for(int i = 0;i<10;i++){if(!bucket[i].empty()){sort(bucket[i].begin(),bucket[i].end());for(int j = 0;j<bucket[i].size();j++){a[pos] = bucket[i][j];pos++;}}}
}
int main()
{double a[10] = {0.2,0.5,0.65,0.59,0.62,0.35,0.48,0.98,0.84,0.56};bucket_sort(a);for(int i = 0;i<10;i++)cout<<a[i]<<"  ";
}

基数排序(O(d*(n+r)))

参考博客:
https://blog.csdn.net/u012580566/article/details/47702955

基数排序就是分别按个位数、十位数…进行排序。
如:
14 37 56 79 93 78 12 65 30
按个位数排完后为:
30 12 93 14 65 56 37 78 79
按十位数排完后为:
12 14 30 37 56 65 78 79 93
排序完成。

int get_max_bit(int* data,int n)
{int num = 1;for(int i = 0;i<n;i++){int bit = 0;int temp_val = data[i];while(temp_val != 0){temp_val /= 10;bit++;}if(bit > num)num = bit;}return num;
}
void max_sort(int* data,int n)
{int tmp[n];int count[10];int num = get_max_bit(data,n);int radio = 1;for(int i = 1;i<=num;i++){// 每次分配前清空计数器for(int j = 0; j < 10; j++)count[j] = 0;// 统计每个桶中的记录数for(int j = 0; j < n; j++){int k = (data[j] / radio) % 10;count[k]++;}// count[j]中存储尾数为0~j的数字的个数for(int j = 1; j < 10; j++)count[j] = count[j - 1] + count[j];// 将所有桶中记录依次收集到tmp中for(int j = n - 1; j >= 0; j--){int k = (data[j] / radio) % 10;tmp[count[k] - 1] = data[j];count[k]--;}// 将临时数组tmp的内容复制到data中for(int j = 0; j < n; j++)data[j] = tmp[j];radio = radio * 10;}
}int main()
{int data[11] = { 73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 196 };max_sort(data,11);for(int i = 0;i<11;i++)cout<<data[i]<<"  ";return 0;
}

时间复杂度:
设最高位数为d位,基数为r(如基数为10,即10进制,最大有10种可能,即最多需要10个桶来映射数组元素),一共n个数。由代码可见,时间复杂度为:O(d(n+r))。空间复杂度为O(dr+n)。

相关文章:

iOS SwiftUI篇-5 专题NavigationView、NavigationLink

iOS SwiftUI篇-5 专题NavigationView、NavigationLink NavigationView:标题、展示模式、隐藏导航栏、隐藏返回按钮、添加导航栏按钮 NavigationLink:Text文本跳转、Image图片跳转、Button按钮跳转、点击按钮根据业务跳转到不同页面 NavigationView 标题、展示模式 import S…

PHP artisan

Artisan 是 Laravel 提供的 CLI&#xff08;命令行接口&#xff09;&#xff0c;它提供了非常多实用的命令来帮助我们开发 Laravel 应用。前面我们已使用过 Artisan 命令来生成应用的 App Key 和控制器。在本教程中&#xff0c;我们会用到以下 Artisan 命令&#xff0c;你也可以…

【转载】Pytorch在加载模型参数时指定设备

转载 https://sparkydogx.github.io/2018/09/26/pytorch-state-dict-gpu-to-cpu/ >>> torch.load(tensors.pt) # Load all tensors onto the CPU >>> torch.load(tensors.pt, map_locationtorch.device(cpu)) # Load all tensors onto the CPU, using a fun…

目标检测之Faster-RCNN的pytorch代码详解(数据预处理篇)

首先贴上代码原作者的github:https://github.com/chenyuntc/simple-faster-rcnn-pytorch&#xff08;非代码作者&#xff0c;博文只解释代码&#xff09; 今天看完了simple-faster-rcnn-pytorch-master代码的最后一个train.py文件&#xff0c;是时候认真的总结一下了&#xff0…

hp-ux 集群,内存 小记

hp-ux 集群&#xff0c;内存 小记 -----查看hp 集群状态信息 # cmviewcl -v CLUSTER STATUS dbsvr up NODE STATUS STATE db01 up running Cluster_Lock_LVM: VOLUM…

iOS SwiftUI篇-6 专题TabView

iOS SwiftUI篇-6 专题TabView TabView: 图片+文字组成tabItem,选中时改变图片和文字颜色 跳转到二级页面时隐藏tabbar,返回到首页时显示tabbar 首页、我的两个tab,效果图: 图片文字组成tabItem,选中时改变图片和文字颜色 代码: struct MainContentView: View {@State…

三维刚体变化中Rcw,tcw的含义

高翔博士的《视觉SLAM十四讲》中&#xff0c;介绍Tcw指从世界坐标w到c的变换矩阵。但研一学机器人学的时候&#xff0c;讲T12的含义是&#xff0c;坐标系2相对于坐标系1的变换。于是一脸懵逼。昨天想了一晚上&#xff0c;有了一点自己的想法&#xff0c;在这记录一下&#xff0…

CV07-DeepLab v3+笔记

目录 一、Dilated Convolution 膨胀卷积 二、ASPP与Encoder & Decoder 三、深度可分离卷积 3.1 深度可分离卷积原理 3.2 深度可分离卷积减小参数量和计算量 3.3 深度可分离卷积实现细节 四、Xception作为Backbone DeepLab v3笔记&#xff0c;记录一些自己认为重要的…

1116.加减乘除

题目描述&#xff1a;根据输入的运算符对输入的整数进行简单的整数运算。 运算符只会是加、减-、乘*、除/、求余%、阶乘&#xff01;六个运算符之一。 输出运算的结果&#xff0c;如果出现除数为零&#xff0c;则输出“error”,如果求余运算的第二个运算数为0&#xff0c;也输出…

Flutter专题1-环境搭建

Flutter专题1-环境搭建和创建项目 这里以MaciOS为例&#xff0c;其他平台参考官网https://flutter.dev/docs/get-started/install 1. 系统要求 系统:macOS (64-bit) 硬盘空间:2.8G 工具:Git 2.获取Flutter SDK 2.1下载SDK,从https://flutter.dev/docs/development/tools/s…

ORB_SLAM2源码:ORBmatcher.cc

ORBmatcher.cc中的函数&#xff0c;主要实现&#xff08;1&#xff09;路标点和特征点的匹配&#xff08;2D-3D点对&#xff09;。&#xff08;2&#xff09;特征点和特征点的匹配&#xff08;2D-2D点对&#xff09;。SearchByProjection的函数重载看得我一脸懵逼。在这做一下笔…

iOS国际化技巧

参考链接:http://www.cocoachina.com/ios/20151120/14258.html http://www.jianshu.com/p/88c1b65e3ddb http://www.cnblogs.com/levilinxi/p/4296712.html http://www.cocoachina.com/appstore/20160310/15632.html http://www.cocoachina.com/ios/20170214/18681.html转载于:…

CV08-数据预处理与数据增强

复现车道线分割项目&#xff08;Lane Segmentation赛事说明在这里&#xff09;&#xff0c;学习数据预处理和数据增强。学习分为Model、Data、Training、Inference、Deployment五个阶段&#xff0c;也就是建模、数据、训练、推断、部署这五个阶段。现在进入的是Data阶段。项目的…

ORB_SLAM2程序入口(System.cc)

程序入口 ORB_SLAM2的程序入口为src/System.cc。在CMakeList.txt中可知&#xff0c;ORB_SLAM2的可执行程序为&#xff1a; Examples/Stereo/stereo_kitti.cc等。 add_executable(stereo_kitti Examples/Stereo/stereo_kitti.cc) target_link_libraries(stereo_kitti ${PROJECT…

HDU 6229 Wandering Robots 找规律+离散化

题目链接&#xff1a;Wandering Robots 题解&#xff1a;先讲一下规律&#xff0c;对于每一个格子它可以从多少个地方来有一个值&#xff08;可以从自己到自己&#xff09;&#xff0c;然后答案就是统计合法格子上的数与所有格子的数的比值 比如说样例的3 0格子上的值就是 3 4 …

app、H5、safari、appstore应用主页评分页之间拉起调用、打开手机某些系统功能、app打开文档

定义打开URL的方法 - (void)openURL:(NSString *)urlStr {NSURL *url [NSURL URLWithString:urlStr];UIApplication *app [UIApplication sharedApplication];if ([app canOpenURL:url]) { #ifdef __IPHONE_10_0[app openURL:url options:[NSDictionary dictionary] complet…

XML学习总结

1、XML结构 2、XmlNodeType值为一个枚举类型&#xff1a; 假设我们对一个XML文件进行遍历&#xff0c;不推断节点是否为Element类型。就会将文本节点遍历出来&#xff0c;出现#test。 3、XmlElement和XmlNode的差别&#xff1a;&#xff08;摘自CSDN论坛&#xff09; &#xff…

Linux01-基本操作与Shell

目录 一、环境 二、Linux目录结构及基本操作 2.1 Linux目录结构 2.2 基本操作 三、shell 3.1 shell的意义 3.2 su - 一、环境 2019年搞下RHCE的证书&#xff0c;但是一直没有整理Linux学习的笔记&#xff0c;为了不让到手的知识被遗忘&#xff0c;从今天起整理Linux学习…

ORB_SLAM2中Tracking线程的三种追踪方式

1、参考关键帧追踪模式 bool Tracking::TrackReferenceKeyFrame()对参考关键帧中的路标点进行跟踪。在Tracking线程中&#xff0c;每传入一帧&#xff0c;都会进行位姿优化。 以上一帧的位姿为当前位姿进行优化。 &#xff08;1&#xff09;计算当前帧的词袋 mCurrentFra…

nodejs 中间件 反向代理 接口转发

背景 随着后端业务系统的增加&#xff0c;纵向需求不断扩展&#xff0c;一个业务系统已经无法满足需求了&#xff0c;衍生出多个业务系统&#xff0c;对外暴露的ip、端口就可能有多个&#xff0c;此时不方便外部接口调用&#xff0c;有些特殊行业客户出于安全性考虑不发提供多…

oneinstack

https://oneinstack.com/转载于:https://www.cnblogs.com/diyunpeng/p/9740895.html

最近在做托盘时,发现 CnTrayIcon1的OnClick 事件,不能被其它按钮来执行,蛋疼。...

比如&#xff1a; procedure TForm1.Button1Click(Sender: TObject);begin CnTrayIcon1.OnClick ; // 这句就是不能通过&#xff01;&#xff01;end; 有过路的高手&#xff0c;指点学生一下。谢谢转载于:https://www.cnblogs.com/hahy8008/p/6783614.html

Linux02-帮助手册

目录 一、man手册 1.1 man的基本使用 1.2 mandb更新文档 二、/usr/share/doc 三、access.redhat.com 门户 一、man手册 1.1 man的基本使用 man就是mannual的缩写&#xff0c;手册的意思。Linux的命令很多&#xff0c;参数选项更多&#xff0c;人脑一般是记不住的&…

ORB_SLAM2中Tracking线程

Tracking线程是ORB_SLAM2的主线程。在System.cc中&#xff0c;使用构造函数进行了初始化&#xff0c;开启了三个线程。 可执行程序—>System构造函数&#xff08;初始化三个线程&#xff09;—>处理输入的帧&#xff08;TrackMonocular&#xff09;—>调用Tracking线程…

selenium的基础知识点

from selenium import webdriver from scrapy.selector import Selector#模拟登陆 browser webdriver.Chrome(executable_pathChromedriver.exe) #路径是Chromedriver.exe的存放位置&#xff0c;windows下只要配置好这个环境就不需要了browser.get(http://w) #需要登陆的那个网…

iOS 直播专题2-音视频采集

从设备(手机)的摄像头、MIC中采集音频、视频的原始数据ios的音视频采集可以从AVFoundation框架里采集 视频采集 这里我们选取GPUImage来采集视频,因为这个框架集成了很多视频滤镜,例如美颜 采集流程: 摄像头采集视频代码 GPUImageVideoCamera.m // 从前摄像头或后摄像头…

bzoj 4871: [Shoi2017]摧毁“树状图”

4871: [Shoi2017]摧毁“树状图” Time Limit: 25 Sec Memory Limit: 512 MBSubmit: 53 Solved: 9[Submit][Status][Discuss]Description 自从上次神刀手帮助蚯蚓国增添了上千万人口&#xff08;蚯口&#xff1f;&#xff09;&#xff0c;蚯蚓国发展得越来越繁荣了&#xff01…

Linux03-本地账户和组

目录 一、本地账户/etc/passwd 二、本地组/etc/group 三、切换账户su - 四、增删改本地账户useradd、userdel、usermod 五、账户默认配置文件/etc/login.defs 六、设置密码passwd(5)命令 七、增删改组groupadd、groupdel和groupmod 八、通过sudo以root身份运行命令 九…

ORB_SLAM2单目初始化策略

基本流程 单目初始化程序存储在Initializer.cc中   需要注意&#xff0c;对于双目/RGB-D相机&#xff0c;初始化时&#xff0c;由于可以直接获得相机的深度信息&#xff0c;因此无需求H/F&#xff0c;直接作为关键帧插入就行。   使用RANSACDLT求解H&#xff0c;RANSAC八点…

Powerdesigner逆向工程64位Oracle数据库

Powerdesigner老版本不支持64位Client&#xff0c;新版本弄不到破解码 解决方法&#xff0c;用Powerdesigner32位Oracle Clent访问64位Oracle Server 遇到的坑分享下 安装完64位的Oracle Server ,32位的 Oracle Clent默认的listener.ora文件有PROGRAM和ENVS这两个节点 Plsql(3…