160 likes | 352 Views
7 查找 (4). 教学目标. 1 、掌握查找的概念,熟练掌握顺序表和有序表(折半查找)的查找算法及其性能分析方法; 2 、掌握二叉排序树的概念,熟练掌握二叉排序树的构造和查找算法及其性能分析方法; 3 、掌握二叉排序树的插入算法,二叉排序树的删除方法; 4 、掌握平衡二叉树的概念,掌握平衡化二叉树的方法; 5 、掌握哈希查找的概念,掌握哈希函数(除留余数法)的构造。 6 、掌握用线性探测法和链地址法解决冲突的方法,并能进行查找长度的计算。 7 、熟悉标准模版库 STL 中的相关知识。. 7 查找. 7.1 静态查找表 7.2 动态查找表
E N D
教学目标 1、掌握查找的概念,熟练掌握顺序表和有序表(折半查找)的查找算法及其性能分析方法; 2、掌握二叉排序树的概念,熟练掌握二叉排序树的构造和查找算法及其性能分析方法; 3、掌握二叉排序树的插入算法,二叉排序树的删除方法; 4、掌握平衡二叉树的概念,掌握平衡化二叉树的方法; 5、掌握哈希查找的概念,掌握哈希函数(除留余数法)的构造。 6、掌握用线性探测法和链地址法解决冲突的方法,并能进行查找长度的计算。 7、熟悉标准模版库STL中的相关知识。
7 查找 7.1 静态查找表 7.2 动态查找表 7.3 哈希表 7.4 查找与标准模版库STL
回顾和复习 1)哈希查找的理想查找长度? 2)影响哈希查找ASL的因素有哪些? 3)哈希表处理冲突的方法主要有哪几种?
7.4 查找与标准模版库STL
四种关联容器 • 集合set • 映射map • 多重集合multiset • 多重映射multimap 头文件分别为:set和map
C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树(Red-Black Tree)。红黑树的统计性能要好于一般的平衡二叉树,所以被STL选择作为了关联容器的内部结构。 显然,set和map均自动排序(因为检索二叉树具有排序的特点) set是集合。 set的特性是集合的基本特性:元素唯一性等。 通过algorithm中提供的includes、set_intersection、set_union、set_difference等四个函数,可以方便的实现集合的包含判断、交、并、差等操作。下面是部分参考用法:
#include<set> #include<algorithm> using namespace std; int main() { int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, b[] = { 3, 6, 8, 9 }; set<int> Sa(a, a+9); set<int> Sb(b, b+4); set<int> Su, Si, Sd; //交集 set_intersection( Sa.begin(), Sa.end(), Sb.begin(),Sb.end(), inserter(Si,Si.begin()) ); //并集 set_union( Sa.begin(), Sa.end(), Sb.begin(), Sb.end(), inserter(Su, Su.begin()) ); //差集 set_difference( Sa.begin(), Sa.end(),Sb.begin(), Sb.end(), inserter(Sd, Sd.begin()) ); // 集合包含判断 bool flag=includes(Sa.begin(), Sa.end(),Sb.begin(), Sb.end()); for(set<int>::iterator it=Si.begin();it!=Si.end();it++) cout<<*it; return 0; }
map简介 map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。对于迭代器来说,可以修改Value值,而不能修改key。 • map的功能 • 自动建立Key - value的对应。key 和 value可以是任意你需要的类型。 • 根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。 • 快速插入Key - Value 记录。 • 快速删除记录 • 根据Key 修改value记录。 • 遍历所有记录。
在map中插入元素 改变map中的条目非常简单,因为map类已经对[]操作符进行了重载 enumMap[1] = "One";enumMap[2] = "Two"; 或 enumMap.insert(map<int, string> :: value_type(2, "Two")) 查找并获取map中的元素 下标操作符给出了获得一个值的最简单方法: string tmp = enumMap[2]; 但是,只有当map中有这个键的实例时才对,否则会自动插入一个实例,值为初始化值。 对这个问题,我们可以使用find()和count()方法来发现一个键是否存在。
从map中删除元素 移除某个map中某个条目用erase() 该成员方法的定义如下 iterator erase(iterator it); //通过一个条目对象删除 iterator erase(iterator first, iterator last); //删除一个范围 size_type erase(const Key& key); //通过关键字删除
#include<map> #include<algorithm> int main() { map<string, int> m; map<string, int>::iterator iter; string s; while(cin>>s){ m[s]++; //很重要的一种插入元素的方法,下标法 m.insert( make_pair(“hello”, 1) ); //插入元素的另一种办法 for(iter = m.begin(); iter != m.end(); ++iter) cout << iter->first << " " << iter->second << endl; //读取元素的办法 iter = m.find("hello"); //查找元素的方法find函数,注意检测的办法 if(iter != m.end()) cout << "yes, found it" << endl; m.erase(iter); //m.erase("world"); //查找元素的方法count函数,返回1或者0,表示有或无 if(m.count("world")==0) cout << "error" << endl; } return 0; }
最新的STL已经支持Hash结构,但VC6.0 不支持 课后建议: • HLoj 8871~8877 • HDoj 1563, 2095 , 1029(Hash) • HDoj 1880(Hash,但内存限制,需要考虑变通) • Poj 2418(BST或 Hash) • Zoj 1899(Hash) • Zoj 1109(BST或 Hash) • 注意收集各类高效hash函数 • 熟悉并尝试使用STL中的查找算法 如:binary_search(A, A + N, value)
推荐2个经典字符串hash函数 unsigned int Hash2(string s) { // 大量采用位运算以提高效率 unsigned int h = 0; for(int i=0; i<s.size(); i++){ h = (h << 4) + s[i]; unsigned int g = h & 0Xf0000000L; if ( g ) h ^= g >> 24; h &= ~g; } return h % MaxN; } unsigned int Hash1(string s) { // zoj 1899 约4000ms AC unsigned int h = 0; for(int i=0; i<s.size(); i++) { h = 31 * h + s[i]; } return h % MaxN; // MaxN就是除留余数法中的p }