这个问题是面试腾讯光子的时候面试官提的,当时的问题是: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为什么保证严格弱序?的更多相关文章

  1. 将三维空间的点按照座标排序(兼谈为std::sort写compare function的注意事项)

    最近碰到这样一个问题:我们从文件里读入了一组三维空间的点,其中有些点的X,Y,Z座标只存在微小的差别,远小于我们后续数据处理的精度,可以认为它们是重复的.所以我们要把这些重复的点去掉.因为数据量不大, ...

  2. 源码阅读笔记 - 1 MSVC2015中的std::sort

    大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...

  3. c++ std::sort函数调用经常出现的invalidate operator<错误原因以及解决方法

    在c++编程中使用sort函数,自定义一个数据结构并进行排序时新手经常会碰到这种错误. 这是为什么呢?原因在于什么?如何解决? 看下面一个例子: int main(int, char*[]) { st ...

  4. 一个std::sort 自定义比较排序函数 crash的分析过程

    两年未写总结博客,今天先来练练手,总结最近遇到的一个crash case. 注意:以下的分析都基于GCC4.4.6 一.解决crash 我们有一个复杂的排序,涉及到很多个因子,使用自定义排序函数的st ...

  5. 科普:std::sort干了什么

    std::sort算是STL中对OIer比较友好的函数了,但你有想过sort是如何保证它的高速且稳定吗? 正文 我们首先来到第一层:sort函数 template<typename _Rando ...

  6. std::sort引发的core

    #include <stdio.h> #include <vector> #include <algorithm> #include <new> str ...

  7. Qt使用std::sort进行排序

    参考: https://blog.csdn.net/u013346007/article/details/81877755 https://www.linuxidc.com/Linux/2017-01 ...

  8. 非常无聊——STD::sort VS 基数排序

    众所周知,Std::sort()是一个非常快速的排序算法,它基于快排,但又有所修改.一般来说用它就挺快的了,代码一行,时间复杂度O(nlogn)(难道不是大叫一声“老子要排序!!”就排好了么...). ...

  9. 今天遇到的一个诡异的core和解决 std::sort

    其实昨天开发pds,就碰到了core,我还以为是内存不够的问题,或者其他问题. 今天把所有代码挪到了as这里,没想到又出core了. 根据直觉,我就觉得可能是std::sort这边的问题. 上网一搜, ...

随机推荐

  1. 半夜了我来发张图 睡觉 ControllerDescriptor 与 ActionDescriptor 之间 的 关系

  2. Maven的学习之路1

    对于下列这段Maven的命令行有不懂之处,在zgmzyr的博客上得到了解释.非常感谢这位博友,写在自己的随笔上以便查看和修改. 1. 创建项目 $ mvn archetype:generate -Dg ...

  3. Java&Eclipse&Maven的折腾

    趁着寒假对于Java的余热,继续了对Java的征途.这次并没有太多琐碎的事情打断我的学习,于是借着这股热情去图书馆借了两本国外的书(中译版),对于程序的爱好一定要坚持下来,才开通了这个博客以坚持学习.

  4. 个人作业四——Alpha测试

    个人作业四--Alpha测试 这个作业属于哪个课程 软件工程 这个作业要求在哪里 作业要求 团队名称 GP工作室 这个作业的目标 对其他小组的项目进行测试 测试人员 许佳文 学号 2017310242 ...

  5. Image Retargeting - 图像缩略图 图像重定向

    Image Retargeting 图像缩略图.图像重定向 前言 这篇文章主要对比DL出现之前的几种上古算法,为了作为DL方法的引子而存在,顺便博客也该更新点新内容上来了,这篇博文就是介绍了我最近在玩 ...

  6. Referer防盗链

    一.目录展示 分为AProject和BProject两个项目进行测试 二.修改c:\windows\system32\drivers\etc下的hosts文件 三.aindex.jsp 四.binde ...

  7. Shell常用命令之curl

    curl命令 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具. ...

  8. Unicode编码解析

    概述 转载自博文浅谈Unicode编码 参考博文,结合自己实际情况进行部分内容添加修改 一 需求 java源码中尤其是数字部分用到了很多Unicode方面知识,如果不懂,看源码的时候会很懵逼 java ...

  9. 从头学pytorch(二十二):全连接网络dense net

    DenseNet 论文传送门,这篇论文是CVPR 2017的最佳论文. resnet一文里说了,resnet是具有里程碑意义的.densenet就是受resnet的启发提出的模型. resnet中是把 ...

  10. 基于Arduino开发的简易“高水位报警系统解决方案”

    长期以来,针对“某些办公室空调没有排水系统,只能用水桶接水,经常造成水漫金山的问题”而提出来的. 材料:Arduino开发板一块.水位传感器一个.高电平蜂鸣器一个.杜邦线若干. 原理:将水位传感器置于 ...