hash冲突的解决办法
https://www.cnblogs.com/wuchaodzxx/p/7396599.html
时间的复杂度:
O(1) 是hash映射,用key值生成hash码作为数组的索引,时间主要在计算hash值。
O(logN) 是二分查找,二叉树。220 =100万,230 =10亿
O(N)线性查找
O(N2) 冒泡查找
hash,能映射不能排序,存储是无序。
二叉树,映射可以排序,也可映射。
LinearMap.h
#ifndef __LINEAR_MAP_H
#define __LINEAR_MAP_H
#include <vector>
// 用vector做的一个简单的map, 线性的, 实际没什么用
template<class Key, class Value>
class LinearMap
{
public:
LinearMap(const int size = 10)
: arr(size), crtSize(0) { }
void Put(const Key& k, const Value& v);
Value Get(const Key& );
private:
struct Data
{
Data(const Key& k = Key(), const Value& v = Value()) // 初始值为T()
: key(k), value(v) { }
Key key;
Value value;
};
std::vector<Data> arr;
int crtSize;
};
template<class Key, class Value>
void LinearMap<Key, Value>::Put(const Key& k, const Value& v)
{
arr[crtSize] = Data(k, v);
crtSize++;
}
template<class Key, class Value>
Value LinearMap<Key, Value>::Get(const Key& k)
{
int i = 0;
while(i < crtSize) // 线性查找, O(N)
{
if(k == arr[i].key)
return arr[i].value;
i++;
}
return Value();
}
#endif
hashMap.h
#ifndef __HASH_MAP_H
#define __HASH_MAP_H
#include <vector>
#include <string>
template<class Key, class Value>
class HashMap
{
public:
HashMap(const int size = 10)
: arr(size), crtSize(0) { }
void Put(const Key& k, const Value& v);
Value Get(const Key& k);
unsigned int hash(const Key& k) const // 计算字符串的hash值 (计算出一个数字 使之唯一代表字符串)
{
unsigned hashVal = 0;
for(size_t i=0; i<k.length(); ++i)
hashVal = hashVal << 7^k[i]; // 每个字符都参与计算
hashVal &= 0x7FFFFFFF;
return hashVal % arr.size(); // 限定到 0~size之间
}
private:
struct Data // (key, value), vector存放的类型就算Data
{
Data(const Key& k = Key(), const Value& v = Value()) // 默认初值T()
: key(k), value(v) { }
Key key;
Value value;
};
std::vector<Data> arr;
int crtSize;
};
template<class Key, class Value>
void HashMap<Key, Value>::Put(const Key& k, const Value& v)
{
if(crtSize == arr.size())
{
std::cerr << "map has fulled.\n";
return; // 超过了
}
arr[hash(k)] = Data(k, v);
crtSize++;
}
template<class Key, class Value>
Value HashMap<Key, Value>::Get(const Key& k)
{
unsigned int h = hash(k);
if(arr[h].key == k) // 通过计算k的hash 查找到的key 和 给定的k 相等才返回正确值
return arr[h].value;
return Value();
}
#endif
main.cpp
#include <iostream>
#include <string>
#include <map> // 映射(字典) 二叉树(红黑树)映射, 不是hash映射
#include <unordered_map> // hash映射
#include "linearMap.h" // 简单map小试验,线性
#include "hashMap.h"
using namespace std;
// hash数据结构, 可做hash集 也可做hash映射 (hash也叫散列), 无法排序
// 所有数据结构中 hash结构速度最快.
// O(N^2) 冒泡
// O(N) 线性查找
// O(logN) 二叉树(二分查找的速度)
// O(1) hash
int main()
{
// 库里的map
cout << "----使用库里的map(二叉树)-----\n";
map<string, int> m; // 二叉树映射
m["a"] = 100;
cout << m["a"] << endl;
cout << "----使用库里的map(hash)-----\n";
unordered_map<string, int> umap; // hash映射
umap["aa"] = 12;
cout << umap["aa"] << endl;
// 自己写的线性map
cout << "-----自写的map(线性)-----\n";
LinearMap<string, int> lm;
lm.Put("aa", 100);
lm.Put("bb", 101);
lm.Put("cc", 102);
cout << lm.Get("bb") << endl;
// 自写的hash map
cout << "-----自写的hash map-----\n";
HashMap<string, int> hm;
hm.Put("aa", 100);
hm.Put("bb", 101);
hm.Put("cc", 102);
hm.Put("dd", 103);
hm.Put("ee", 104);
hm.Put("ff", 105);
hm.Put("gg", 106);
hm.Put("hh", 107);
hm.Put("ii", 108);
hm.Put("jj", 109);
cout << hm.Get("aa") << endl;
cout << hm.Get("bb") << endl;
cout << hm.Get("cc") << endl;
cout << hm.Get("dd") << endl;
cout << hm.Get("ee") << endl;
cout << hm.Get("ff") << endl;
cout << hm.Get("gg") << endl;
cout << hm.Get("hh") << endl;
cout << hm.Get("ii") << endl;
cout << hm.Get("jj") << endl;
/* output:
----使用库里的map(二叉树)-----
100
----使用库里的map(hash)-----
12
-----自写的map(线性)-----
101
-----自写的hash map-----
100
101
102
103
104
105
106
107
108
109
*/
return 0;
}
库里的hash映射用法
include <unordered_map> // 0. include the library
int main() {
// 1. initialize a hash map
unordered_map<int, int> hashmap;
// 2. insert a new (key, value) pair
hashmap.insert(make_pair(0, 0));
hashmap.insert(make_pair(2, 3));
// 3. insert a new (key, value) pair or update the value of existed key
hashmap[1] = 1;
hashmap[1] = 2;
// 4. get the value of a specific key
cout << "The value of key 1 is: " << hashmap[1] << endl;
// 5. delete a key
hashmap.erase(2);
// 6. check if a key is in the hash map
if (hashmap.count(2) <= 0) {
cout << "Key 2 is not in the hash map." << endl;
}
// 7. get the size of the hash map
cout << "the size of hash map is: " << hashmap.size() << endl;
// 8. iterate the hash map
for (auto it = hashmap.begin(); it != hashmap.end(); ++it) {
cout << "(" << it->first << "," << it->second << ") ";
}
cout << "are in the hash map." << endl;
// 9. clear the hash map
hashmap.clear();
// 10. check if the hash map is empty
if (hashmap.empty()) {
cout << "hash map is empty now!" << endl;
}
}
库里的hash集用法
#include <unordered_set> // 0. include the library
int main() {
// 1. initialize a hash set
unordered_set<int> hashset;
// 2. insert a new key
hashset.insert(3);
hashset.insert(2);
hashset.insert(1);
// 3. delete a key
hashset.erase(2);
// 4. check if the key is in the hash set
if (hashset.count(2) <= 0) {
cout << "Key 2 is not in the hash set." << endl;
}
// 5. get the size of the hash set
cout << "The size of hash set is: " << hashset.size() << endl;
// 6. iterate the hash set
for (auto it = hashset.begin(); it != hashset.end(); ++it) {
cout << (*it) << " ";
}
cout << "are in the hash set." << endl;
// 7. clear the hash set
hashset.clear();
// 8. check if the hash set is empty
if (hashset.empty()) {
cout << "hash set is empty now!" << endl;
}
}