- 论坛徽章:
- 0
|
Center of STL Study
——最优秀的STL学习网站
条款44:尽量用成员函数代替同名的算法
有些容器拥有和STL算法同名的成员函数。关联容器提供了count、find、lower_bound、upper_bound和
equal_range,而list提供了remove、remove_if、unique、sort、merge和reverse。大多数情况下,你应该用成员函
数代替算法。这样做有两个理由。首先,成员函数更快。其次,比起算法来,它们与容器结合得更好(尤其
是关联容器)。那是因为同名的算法和成员函数通常并不是是一样的。
我们以对关联容器的实验开始。假如有一个set<int>,它容纳了一百万个元素,而你想找到元素727的第一个
出现位置(如果存在的话)。这儿有两个最自然的方法来执行搜索:
set<int> s; // 建立set,放入1,000,000个数据
...
set<int>::iterator i = s.find(727); // 使用find成员函数
if (i != s.end()) ...
set<int>::iterator i = find(s.begin(), s.end(), 727); // 使用find算法
if (i != s.end()) ...
find成员函数运行花费对数时间,所以不管727是否存在于此set中,set::find只需执行不超过40次比较来查找
它,而一般只需要大约20次。相反,find算法运行花费线性时间,所以如果727不在此set中,它需要执行
1,000,000次比较。即使727在此set中,也平均需要执行500,000次比较来找到它。效率得分如下:
find成员:大约40(最坏的情况)至大约20(平均情况)
find算法:1,000,000(最坏的情况)至500,000(平均情况)
和高尔夫比赛一样,分值低的赢。正如你所见,这场比赛结果没什么可说的。
我必须对find成员函数所需的比较次数表示小小的谨慎,因为它有些依赖于关联容器的实现。绝大部分的实
现是使用的红黑树——平衡树的一种——失衡度可能达到2。在这样的实现中,对一百万个元素的set进行搜
索所需最多的比较次数是38次。但对绝大部分的搜索情况而言,只需要不超过22次。一个基于完全平衡树的
实现绝不需要超过21次比较,但在实践中,完全平衡树的效率总的来说不如红黑树。这就是为什么大多数的
STL实现都使用红黑树。 |
|