std::sort为什么保证严格弱序?
这个问题是面试腾讯光子的时候面试官提的,当时的问题是:sort自定义comp函数能用>=吗?当时的我想comp函数只要函数签名是对的应该就没问题吧,于是答了可以。面试结束后总感觉哪里不对,耿耿于怀,几番搜寻也只找到说要保证严格弱序,原理网上基本却没有。只能求助于源码了,打开<<STL源码剖析>>,看了一遍sort的实现,还是没能找出问题所在(这里要给自己提个醒,思考得不够)。我不服,又在网上搜索了一遍结合源码,终于找到了答案。
首先补充一下满足严格弱序的3个条件:
1.两个关键字不能同时严格弱序于对方。
2.如果a严格弱序于b,且b严格弱序于c,则a必须严格弱序于c。
3.如果存在两个关键字,任何一个都不严格弱序于另一个,则这两个关键字是相等的。
sort采用的排序算法是IntroSort,是一种混合型算法。简单来说就是利用快排将要排序的数组分隔成大致有序的几段, 根据递归深度和分隔开的小段长度情况看是否采取堆排序,最后再进行插入排序。这样的话能在最坏情况下将时间复杂度推进到O(nlogn)。在SGISTL实现的插入排序是这么写的:
void __unguarded_linear_insert(RandomAccessIterator last, T value)
{
RandomAccessIterator next = last;
--next;
while(value < *next)
{
*last = *next;
last = next;
--next;
}
*last = value;
}
将注意力放在第5行的while循环上,你会发现这里并没有判断边界,原因是stl以严格弱序为前提且在进入这个函数前会保证有哨兵在数组的前方。(这里代码是直接使用的小于,使用自定义comp的时候将while里的<判断换成comp理解就可以了。)
那么如果我们元素不严格弱序的话,在全是相等元素的情况下,这个while会无限循环下去,最终造成数组越界!
其实不止在插入排序这块,在快速排序进行分割的时候也会出现类似的问题,这里就不再多说了。
std::sort为什么保证严格弱序?的更多相关文章
- 将三维空间的点按照座标排序(兼谈为std::sort写compare function的注意事项)
最近碰到这样一个问题:我们从文件里读入了一组三维空间的点,其中有些点的X,Y,Z座标只存在微小的差别,远小于我们后续数据处理的精度,可以认为它们是重复的.所以我们要把这些重复的点去掉.因为数据量不大, ...
- 源码阅读笔记 - 1 MSVC2015中的std::sort
大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...
- c++ std::sort函数调用经常出现的invalidate operator<错误原因以及解决方法
在c++编程中使用sort函数,自定义一个数据结构并进行排序时新手经常会碰到这种错误. 这是为什么呢?原因在于什么?如何解决? 看下面一个例子: int main(int, char*[]) { st ...
- 一个std::sort 自定义比较排序函数 crash的分析过程
两年未写总结博客,今天先来练练手,总结最近遇到的一个crash case. 注意:以下的分析都基于GCC4.4.6 一.解决crash 我们有一个复杂的排序,涉及到很多个因子,使用自定义排序函数的st ...
- 科普:std::sort干了什么
std::sort算是STL中对OIer比较友好的函数了,但你有想过sort是如何保证它的高速且稳定吗? 正文 我们首先来到第一层:sort函数 template<typename _Rando ...
- std::sort引发的core
#include <stdio.h> #include <vector> #include <algorithm> #include <new> str ...
- Qt使用std::sort进行排序
参考: https://blog.csdn.net/u013346007/article/details/81877755 https://www.linuxidc.com/Linux/2017-01 ...
- 非常无聊——STD::sort VS 基数排序
众所周知,Std::sort()是一个非常快速的排序算法,它基于快排,但又有所修改.一般来说用它就挺快的了,代码一行,时间复杂度O(nlogn)(难道不是大叫一声“老子要排序!!”就排好了么...). ...
- 今天遇到的一个诡异的core和解决 std::sort
其实昨天开发pds,就碰到了core,我还以为是内存不够的问题,或者其他问题. 今天把所有代码挪到了as这里,没想到又出core了. 根据直觉,我就觉得可能是std::sort这边的问题. 上网一搜, ...
随机推荐
- GP工作室—团队项目总结
GP工作室-团队项目总结 这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/GeographicInformationScience/ 这个作业要求在哪里 ...
- Linux程序守护脚本
不废话,直接上脚本,[]注释的下发语句需要按需替换: #!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/us ...
- 解决IDEA使用lombok注解无效,@Data不生效问题
在settings设置启用注解即可:
- Linux(Centos)安装tomcat并且部署Java Web项目
步骤一.下载安装包 a. 下载tomcat linux安装包,地址:http://tomcat.apache.org/download-80.cgi , 我们下载的版本是8.0,下载方式如图: b ...
- CUDA学习(二)之使用clock()函数
clock()函数是C/C++中的计时函数,相关的数据类型是clock_t,使用clock函数可以计算运行某一段程序所需的时间,如下所示程序计算从10000000逐渐减一直到0所需的时间. #incl ...
- DOCKER 学习笔记4 认识DockerCompose 多容器编排
前言 通过上一节的学习,学会了如何在Linux 环境下搭建Docker并且部署Springboot 项目,并且成功的跑了起来,当然,在生产环境中,不只是需要一个后端的Web 项目,还需要比如 Ngin ...
- C++ 函数详解
C++函数完全兼容C函数定义的风格,但是也做出了一些改进.一方面,C++函数允许使用缺省参数值和占位参数:另一方面,C++提供了重要的函数重载机制:另外,为了解决C中臭名昭著的宏缺陷问题,C++提供了 ...
- Hadoop-3.1.2安装步骤
Hadoop-3.1.2 安装步骤 第一步 准备 服务器配置 1. 在VMware中安装把Centos7安装成功后,需要把界面设置为命令行启动,因为默认的启动方式是图形界面启动 systemctl ...
- C语言遇到的关于清除标准输入缓冲区的问题[编程入门]
关于标准输入缓冲区的一个易犯的小错误 之前写了个简易的登录程序,但显然这不像写Java时那么容易(只要思路对,基本没问题).一不留神就出现了小BUG! 以下是错误的源代码: #include < ...
- Linux基础与搭建
1 学习目标 了解Linux的简介与安装 掌握Linux常用的命令 掌握Linux系统上JDK.Mysql.Tomcat的安装 2 Linux简介 2.1 Unix简介 Unix是一个强大的多用户. ...