数据结构与算法(C++) hash映射 线性映射 字符串hash值计算 库里的hash集映射使用方法

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值