C++程序设计:原理与实践(进阶篇)16.8 排序和搜索

简介:

16.8 排序和搜索


我们经常希望自己的数据是有序的。为达到这个目的,我们可以使用一个能维护顺序的数据结构,例如map或set,或进行排序。在STL中,最常见和有用的排序操作是sort(),我们已经使用过多次了。在默认情况下,sort()使用<作为排序标准,但是我们也可以提供自己的标准:

 

作为一个基于用户指定规则进行排序的例子,我们将介绍如何进行不考虑大小写的字符串排序:

 

 

一旦一个序列已排序,我们不再需要用f?ind()从开始位置进行搜索;我们可以利用这种序进行二分搜索。二分搜索的基本工作原理如下:

假设我们在查找值x,查看中间元素:

如果元素的值等于x,我们已经找到它!

如果元素的值小于x,则值等于x的任何元素必然位于右边,因此我们查找右半部分(在这半部分进行二分查找)。

如果元素的值大于x,则值等于x的任何元素必然位于左边,因此我们查找左半部分(在这半部分进行二分查找)。

如果我们已经到达最后一个元素(向左或向右),也没有找到x,那么没有等于值x的元素。

对于更长的序列,二分搜索比f?ind()(线性搜索)的速度更快。二分搜索的标准库算法是binary_search()和equal_range()。我们说的“更长”的含义是什么呢?这要视具体情况而定,但即使序列中只有10个元素,也足以体现出binary_search()相对于f?ind()的优势。对于一个有1000个元素的序列,binary_search()可能要比f?ind()快200倍,因为其代价为O(log2(N)),参见16.6.4节。

binary_search算法有两种变形:

 

这些算法要求和假设输入序列是已排序的。如果未排序,“有趣的事情”如无限循环就可能会发生。binary_search()简单地告诉我们一个值是否存在:

 

因此,如果我们只关心一个值是否在序列中,binary_search()是理想的。如果我们还关心找到的元素,可以使用low_bound()、upper_bound()或equal_range()(参见附录C.5.4和23.4节)。有些情况下我们关心找到的是哪个元素,原因通常是对象包含更多信息而不仅仅是一个关键字,而很多元素可能具有相同的关键字,或者是我们希望找到符合搜索标准的元素。

相关文章
|
1月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
存储 C++
【C++篇】C++类和对象实践篇——从零带你实现日期类的超详细指南
【C++篇】C++类和对象实践篇——从零带你实现日期类的超详细指南
24 2
【C++篇】C++类和对象实践篇——从零带你实现日期类的超详细指南
|
1月前
|
存储 编译器 C语言
C++类与对象深度解析(一):从抽象到实践的全面入门指南
C++类与对象深度解析(一):从抽象到实践的全面入门指南
49 8
|
1月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
39 1
|
1月前
|
存储 算法 C++
【搜索算法】 跳马问题(C/C++)
【搜索算法】 跳马问题(C/C++)
|
1月前
|
人工智能 算法 Java
【搜索算法】数字游戏(C/C++)
【搜索算法】数字游戏(C/C++)
|
2月前
|
C++
c++继承层次结构实践
这篇文章通过多个示例代码,讲解了C++中继承层次结构的实践应用,包括多态、抽象类引用、基类调用派生类函数,以及基类指针引用派生类对象的情况,并提供了相关的参考链接。
|
4月前
|
算法 C++
【C++高阶】高效搜索的秘密:深入解析搜索二叉树
【C++高阶】高效搜索的秘密:深入解析搜索二叉树
42 2