http://www.169it.com/article/3215620760.html

http://www.cnblogs.com/sharpfeng/archive/2012/09/18/2691096.html

在C++的STL库中,要实现排序可以 通过将所有元素保存到vector中,然后通过sort算法来排序,也可以通过multimap实现在插入元素的时候进行排序。在通过 vector+sort进行排序时,所有元素需要先存入vector容器中,sort在排序时又需要将元素全部取出来再进行排序。multimap底层实 现为红黑树,因此元素在插入的过程中就实现了排序。那么到底哪一种排序速度更快呢?

下面有一个测试程序:

#include <vector>
#include <set>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
using namespace std;
double time() {
  struct timeval tv;
  if (gettimeofday(&tv, NULL) != 0) return 0.0;
  return tv.tv_sec + tv.tv_usec / 1000000.0;
}
struct Score {
  string name;
  double score;
  bool operator <(const Score& right) const {
    return score < right.score;
  }
};
int main(int argc, char** argv) {
  vector<Score> src;
  for (int i = 0; i < 10000000; i++) {
    int num = rand();
    char buf[32];
    sprintf(buf, "%d", num);
    Score score = { buf, num };
    src.push_back(score);
  }
  {
    double stime = time();
    vector<Score> res;
    for (vector<Score>::const_iterator it = src.begin();
         it != src.end(); ++it) {
      res.push_back(*it);
    }
    sort(res.begin(), res.end());
    double etime = time();
    printf("vector: %f\n", etime - stime);
  }
  {
    double stime = time();
    multiset<Score> res;
    for (vector<Score>::const_iterator it = src.begin();
         it != src.end(); ++it) {
      res.insert(*it);
    }
    double etime = time();
    printf("multiset: %f\n", etime - stime);
  }
  return 0;
}

程序运行结果为:

         time
vector   4.776060
multiset 10.761023

在这个测试中,vector+sort排序比multiset(multimap实现基于multiset)快多了。快速排序是目前已知的所有排序算法中最快的排序算法,因此它比基于堆排序的multiset快。

在这个测试结果出来之前,大多数人都会毫无疑问地认为multiset排序要更快。这也是有原因的,快速排序速度虽然快,但是在实际的运行过程中,它需 要大量地拷贝元素,其拷贝操作的时间复杂度为o(NlogN),而基于红黑树的multiset在排序的过程中则避免了元素的拷贝。如果元素的内存占用空 间比较大,那么multiset排序的速度将比vector+sort快。为了测试这个结果,将上面测试程序中的结构体改为:

struct Score {
  string name1;
  string name2;
  string name3;
  string name4;
  double score;
  bool operator <(const Score& right) const {
    return score < right.score;
  }
};

然后重新编译运行测试程序,测试结果为:

         time
vector   12.955739
multiset 11.368364

这个测试结果和我们的预期一致。

总之,我们在使用STL的排序算法时,需要根据不同的元素构造来进行合适的选择,如果都是比较简单的元素,那么适合选择vector+sort来进行排 序,对于由字符串构成的占用了比较大的空间的复杂元素,应该使用multiset。如果排序的元素的总个数比较少,那么选择任意一种都可以。

list支持快速的插入和删除,但是查找费时;

vector支持快速的查找,但是插入费时。

map查找的时间复杂度是对数的,这几乎是最快的,hash也是对数的。
如果我自己写,我也会用二叉检索树,它在大部分情况下可以保证对数复杂度,最坏情况是常数复杂度,而std::map在任何情况下都可以保证对数复杂度,原因是它保证存诸结构是完全二叉检索树,但这会在存诸上牺牲一些时间。

STL   中的   map   内部是平衡二叉树,所以平衡二叉树的性质都具备。查找数据的时间也是对数时间。 vector,在分配内存上一般要比   new   高效的多。

为什么说   hash_map   是对数级的?在不碰撞的情况下,hash_map是所有数据结构中查找最快的,它是常数级的。
如果对问题设计了足够好的hash算法,保证碰撞率很低,hash_map的查找效率无可置疑。
另外,STL的map,它的查找是对数级的,是除hash_map外最高的了,你可以说“也许还有改进余地”,但对于99.9999%的程序员,设计一个比STL   map好的map,我执悲观态度。
STL的map有平衡策略(比如红黑树什么的),所以不会退化,不需要考虑数据本身的分布问题。只不过,如果数据本身是排好序的,用vector或heap会明显的快些,因为它们的访问比较简单。


想没必要怀疑stl::map的查找效率,影响效率最主要的因素是什么?算法,在查找问题上,有什么算法比RB_tree更好吗?至少现在还没有。不否
认你可以通过自己写代码,设计一个符合你需要的BR—TREE,比stl::map简捷那么一点,但最多也就每次迭代中少一行指令而已,处理十万个数据多
执行十万行指令,这对你重要吗?如果你不是在设计OS像LINUX,没人会关注这十万行指令花的时间。
rb-tree的时间花在了插入和删除上,如果你不是对插入和删除效率要求很高,你没有理由不选择基于rb-tree的stl::map。

大多数程序员写不出比std::map更好的map,这是当然的。然而并不是std::map的所有特性都出现在我们的程序中,自己编写的可以更适合自己的程序,的确会比std::map更快一些。

关于hash_map,它与map的实现机制是不一样的,map内部一般用树来实现,其查找操作是O(logN)的,这个没有争议,我就不多说了。
hash_map
的查找,内部是通过一个从key到value的运算函数来实现的,这个函数“只接受key作为参数”,也就是说,hash_map的查找
算法与数据量无关,所以认为它是O(1)级的。来这里的应该都是达人,可以参看《数据结构》。当然,事实总不这样完美,再引一段前面我自已说的话,进一步
说明,以免误会:

-----------------------------------------
在不碰撞的情况下,hash_map是所有数据结构中查找最快的,它是常数级的。
------------------------------------------
注意我的前提:“在不碰撞的情况下”,其实换句话说,就是要有足够好的hash函数,它要能使key到value的映射足够均匀,否则,在最坏的情况下,它的计算量就退化到O(N)级,变成和链表一样。
如果说   hash_map   是所有容器中最慢的,也只能说:“最拙劣的hash函数”会使hash_map成为查找最慢的容器。但这样说意义不大,因为,最凑巧的排列能使冒泡排序成为最快的排序算法。

BS: "对于大型容器而言,hash_map能够提供比map快5至10倍的元素查找速度是很常见的,尤其是在查找速度特别重要的地方.另一方面,如果hash_map选择了病态的散列函数,他也可能比map慢得多. "

ANSIC++在1998年之后就没再有重大改变,并且决定不再向C++标准库中做任何重大的变更,正是这个原因,hash   table(包括hash_map)并没有被列入标准之中,虽然它理应在C++标准之中占有一席之地。
虽然,现在的大多数编译平台支持hash   table,但从可移植性方面考虑,还是不用hash   table的好。

hehe俺也来凑凑热闹。
1.有的时候vector可以替代map
比如key是整数,就可以以key的跨度作为长度来定义vector。
数据规模很大的时候,差异是惊人的。当然,空间浪费往往也惊人。
2.hash是很难的东西
没有高效低碰撞的算法,hash_xxx没有意义。
而对不同的类型,数据集,不可能有优良的神仙算法。必须因场合而宜。
俺有的解决方法是GP,可不是饭型,是遗传编程,收效不错。

你的百万级的数据放到vector不大合适。因为vector需要连续的内存空间,显然在初始化这个容器的时候会花费很大的容量。
使用map,你想好了要为其建立一个主键吗?如果没有这样的需求,为什么不考虑deque或者list?
map默认使用的是deque作为容器。其实map不是容器,拿它与容器比较意义不大。因为你可以配置它的底层容器类型。

如果内存不是考虑的问题。用vector比map好。map每插入一个数据,都要排序一次。所以速度反不及先安插所有元素,再进行排序。

用 binary_search对已序区间搜索,如果是随机存取iterator,则是对数复杂度。可见,在不考虑内存问题的情况下,vector比map 好。

如果你需要在数据中间进行插入,list 是最好的选择,vector   的插入效率会让你痛苦得想死。

涉及到查找的话用map比较好,因为map的内部数据结构用rb-tree实现,而用vector你只能用线性查找,效率很低。

stl还提供了 hash容器,理论上查找是飞快~~~。做有序插入的话vector是噩梦,map则保证肯定是按key排序的,list要自己做些事情。

HASH类型的查找肯定快,是映射关系嘛,但是插入和删除却慢,要做移动操作, LIST类型的使链式关系,插入非常快,但是查找却费时,需要遍历~~ , 还是用LIST类型的吧,虽然查找慢点,

先快速排序,然后二分查找,效率也不低

最新文章

  1. JavaScript动画知多少?
  2. 如何在Visual Studio里面查看程序的汇编代码?
  3. CodeIgniter2.2.0-在控制器里调用load失败报错的问题
  4. asp.net导出word(word2007)
  5. 如果类的属性是copy的NSString类型 用set方法拦截时
  6. RESTful API 设计最佳实践(转)
  7. ASP.NET 去除所有HTML标记的方法
  8. swift 开篇
  9. linux系统编程:进程间通信-mmap
  10. 用CSS样式画横线和竖线的方法
  11. Yii2中把路由地址中的%2F改为/
  12. shell脚本中获取当前所在目录地址
  13. queue源码
  14. (转)Java动态追踪技术探究
  15. Zabbix监控Tomcat案例
  16. 常见HTTP状态码及URL编码表
  17. Keepalived基础知识-运维小结
  18. Opencv打开摄像头,读不到图像,一般来说先读取第一帧,舍弃,然后就正常了
  19. javascript实现金额大写转换函数
  20. python作业之生成随机数

热门文章

  1. VIM使用学习笔记 : 按键说明
  2. 【Android面试】Android面试题集锦 (陆续更新)(最新2012-6-18) eoe上看到的
  3. 关于tableView的错误提示
  4. android oom 全解析
  5. STL标准模板库介绍
  6. 如何预览github中的html页面
  7. IC/RFID/NFC 关系与区别
  8. BZOJ 1014: [JSOI2008]火星人prefix
  9. Python自动化之select、greenlet和gevent和事件驱动模型初探
  10. Docker内部存储结构(devicemapper)解析(续)