C++ 为什么map.find使用<;运算符和not==运算符?

C++ 为什么map.find使用<;运算符和not==运算符?,c++,stdmap,C++,Stdmap,当我试图找出我的程序有缺陷的原因时,我发现: 在std::map中,使用小于操作符对键进行比较,因为std::map是排序的,所以可以利用小于x的所有元素位于x之前,而大于x的所有元素位于x之后这一事实。这意味着您可以找到一个元素,这比线性搜索(即仅按顺序查看每个元素)有效得多 例如,在一个集合中有效地查找数字55可以如下所示: 1 1 2 3 5 8 13 21 34 55 89 144 [ ^ ] 8 is too low 1 1

当我试图找出我的程序有缺陷的原因时,我发现:


std::map
中,使用小于
操作符对键进行比较,因为
std::map
是排序的,所以可以利用小于
x
的所有元素位于
x
之前,而大于x的所有元素位于
x
之后这一事实。这意味着您可以找到一个元素,这比线性搜索(即仅按顺序查看每个元素)有效得多

例如,在一个集合中有效地查找数字55可以如下所示:

 1 1 2 3 5 8 13 21 34 55 89 144
[          ^                   ]  8 is too low

 1 1 2 3 5 8 13 21 34 55 89 144
            [      ^           ]  34 is too low

 1 1 2 3 5 8 13 21 34 55 89 144
                     [   ^     ]  89 is too high

 1 1 2 3 5 8 13 21 34 55 89 144
                     [^ ]         55 is a match!

这有复杂度O(logn),而仅仅与
==
比较就有复杂度O(n)。换句话说,在一百万个元素的地图中找到一个元素只需要大约log2(106)&approw;20个比较,而如果我们与
==
进行比较,则需要大约106个比较,这对于大型收藏来说是一个巨大的差异。

最让您困惑的可能是您所引用的链接中的这句话:

我已经创建了一个哈希映射

然而,这是不正确的
std::map
是一个树映射,通常由红黑树实现

现在,您的问题基本上转向数据结构问题

红黑树是一种二叉搜索树,其中的每个节点都具有以下属性:

  • 节点的左子节点小于当前节点
  • 节点的右子节点大于当前节点
请注意,我使用“少”或“大”只是为了让您理解。更准确地说,给定一个用于组织满足严格弱序要求的树的二元谓词
p
,我们假设当前节点为N,然后:

  • p(N,N->left)
    为真
  • p(N,N->右)
    为false
因此,现在您位于树的顶部,要找到正确的节点,您需要不断将您拥有的值与当前节点进行比较,并决定您应该走哪个方向

你可能会问为什么
==
不是必需的,那是因为当谓词p满足严格弱序的要求时,以下两个表达式是等价的(不精确,但至少我们关心的部分是等价的):

A.
!(p(A,B)| p(B,A))

B.
A==B


你可以问自己,当A不小于B且B不小于A时,A和B之间的关系是什么?

因为使用
进行搜索你是否玩过这种猜测游戏,从1到100中选择一个数字?你的第一个问题是,你的数字是否小于50,而不是等于50。