精华内容
下载资源
问答
  • C++哈希表

    2020-10-30 15:27:45
    2、定义一个哈希表(我们以Key和Value都是int变量为例): unordered_map<int,int> Hash; 3、哈希表的建立有下面几种方法: Hash[1]=3; Hash.insert<make_pair(1,3)>; Hash.insert({ {1,3},{2,4} }); 4...

    unordered_map的使用

    1、头文件:

    #include<unordered_map> 
    

    2、定义一个哈希表(我们以Key和Value都是int变量为例):

    unordered_map<int,int> Hash;
    

    3、哈希表的建立有下面几种方法:

    Hash[1]=3;
    Hash.insert<make_pair(1,3)>;
    Hash.insert({ {1,3},{2,4} });
    

    4、迭代器:

    unordered_map<int,int>::iterator it;
    

    5、利用迭代器访问变量:

    it->first;
    it->second;
    

    6、哈希表的查找:

    it=Hash.find(1);
    

    若找不到,返回的是Hash.end();

    7、修改哈希表:

    Hash[1] = 4;
    

    8、清除哈希表:

    Hash.erase(1);
    Hash.clear();
    
    展开全文
  • c++ 哈希表

    2020-10-26 11:10:00
    文章目录前言一、什么是哈希/散列...但是unordered_map和unordered_set的效率是O(1),而它的底层原理就是哈希表 一、什么是哈希/散列? 构造一种存储结构,通过某种函数使元素的存储位置与它的关键码之间能够建立一一映


    前言

    在学习完map和set后,我们会惊讶于它的效率O(logn)。
    但是unordered_map和unordered_set的效率是O(1),而它的底层原理就是哈希表

    一、什么是哈希/散列?

    构造一种存储结构,通过某种函数使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。哈希方法中使用的转换函数称为哈希(散列)函数,构造出来的结构称为哈希表(Hash Table)(或者称散列表)

    二、什么是哈希冲突?如何解决

    不同关键字通过相同哈希哈数计算出相同的哈希地址,会导致哈希冲突

    1.开放定制法(闭散列)

    1. 线性探测
      线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。
    2. 二次探测
      找下一个空位置的方法为: = ( + )% m,或者: = ( - )% m。其中:i = 1,2,3…, 是通过散列函数Hash(x)对元素的关键码 key 进行计算得到的位置,m是表的大小

    2.拉链法(开散列)

    开散列法又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,具有相同地址的关键码归于同一子集合,每一个子集合称为一个桶,各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中。

    三、如果哈希表中冲突得很厉害怎么办?

    1.​控制负载因子
    ​2.使用拉链法,如果一个冲突链到达一定长度,就不用链表,转换成红黑树

    四、unordered_map和unordered_set跟map/set的区别?

    一个底层是哈希表,时间复杂度O(1),遍历出来无序

    ​一个是红黑树,时间复杂度O(logN) ,遍历出来有序

    map和set是双向迭代器,unordered_map和unordered_set是单向迭代器

    总结

    应用链地址法处理溢出,需要增设链接指针,似乎增加了存储开销。事实上: 由于开地址法必须保持大量的空闲空间以确保搜索效率,如二次探查法要求装载因子a <= 0.7,而表项所占空间又比指针大的多,所以使用链地址法反而比开地址法节省存储空间。

    面试题:

    给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中?
    解决方案:
    1.排序,二分查找
    2.set/unordered_set(红黑树/哈希表)存起来再查找
    以上方案的问题:数据量太大,放不到内存(16G)
    那么解决方法是:位图,高效且节省空间 (500M)

    展开全文
  • 实现哈希表的两种方法: 哈希(散列)函数的定义 关键值key: 实现过程: 键值对和Entry(一个意思) 哈希冲突: 处理哈希冲突的方法: 1、开放寻址法 2、拉链法 3、冲突过多 哈希表的扩容: 本文根据...

    实现哈希表的两种方法:

    哈希(散列)函数的定义

     关键值key:

    实现过程:

     键值对和Entry(一个意思)

    哈希冲突:

     处理哈希冲突的方法:

    1、开放寻址法

    2、拉链法

    3、冲突过多

    哈希表的扩容:


    常用的函数方法!!!:

    https://blog.csdn.net/Peealy/article/details/116895964?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162942757216780357268753%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162942757216780357268753&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-5-116895964.pc_search_result_cache&utm_term=C%2B%2B%E5%93%88%E5%B8%8C%E8%A1%A8%E7%9A%84%E6%9F%A5%E6%89%BE%E5%87%BD%E6%95%B0&spm=1018.2226.3001.4187

    本文根据以下地址进行再一次整理

    https://blog.csdn.net/sinat_33921105/article/details/103344078?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162613581416780262550821%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162613581416780262550821&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-103344078.first_rank_v2_pc_rank_v29&utm_term=%E5%93%88%E5%B8%8C%E8%A1%A8&spm=1018.2226.3001.4187

    首先我们需要知道的是哈希表的本质是一个数组

    实现哈希表的两种方法:

    1、数组+链表

    2、数组+二叉树

    哈希(散列)函数的定义

     关键值key:

    就比如想要去查一个人的电话号码,那么此时我们可以将他的名字当作是关键词。

    实现过程:

     键值对和Entry(一个意思)

    键值对,就是我们经常说的key-value,简单点说就是一个值对应另外一个值,比如a对应b,那么a就是key,b是value,哈希表存放的就是这样的键值对,在哈希表中是通过哈希函数将一个值映射到另外一个值的,所以在哈希表中,a映射到b,a就叫做键值,而b呢?就叫做a的哈希值,也就是hash值。

    总结下来就是键值对和Entry保存的是key和value两个值

    哈希冲突:

    比如现在张三和李四就发生了哈希冲突

     处理哈希冲突的方法:

    1、开放寻址法

    这里所说的开放寻址法其实简单来说就是,既然位置被占了,那就另外再找个位置不就得了,怎么找其他的位置呢?这里其实也有很多的实现,我们说个最基本的就是既然当前位置被占用了,我们就看看该位置的后一个位置是否可用,也就是1的位置被占用了,我们就看看2的位置,如果没有被占用,那就放到这里呗,当然,也有可能2的位置也被占用了,那咱就继续往下找,看看3的位置,一次类推,直到找到空位置。

    2、拉链法

     拉链法则不同,还是在该位置,可是,该位置被占用了咋整,这里采用的是链表,就像图中所示,现在张三和李四都要放在1找个位置上,但是张三先来的,已经占了这个位置,待在了这个位置上了,那李四呢?解决办法就是链表,这时候这个1的位置存放的不单单是之前的那个Entry了,此时的Entry还额外的保存了一个next指针,这个指针指向数组外的另外一个位置,将李四安排在这里,然后张三那个Entry中的next指针就指向李四的这个位置,也就是保存的这个位置的内存地址,如果还有冲突,那就把又冲突的那个Entry放在一个新位置上,然后李四的Entry中的next指向它,这样就形成了一个链表。

    3、冲突过多

    如果冲突过多的话,这块的链表会变得比较长,怎么处理呢?这里举个例子吧,拿java集合类中的HashMap来说吧,如果这里的链表长度大于等于8的话,链表就会转换成树结构,当然如果长度小于等于6的话,就会还原链表。以此来解决链表过长导致的性能问题。

    中间有个7作为一个差值,来避免频繁的进行树和链表的转换,因为转换频繁也是影响性能的啊。

    哈希表的扩容:

    当哈希表被占的位置比较多的时候,出现哈希冲突的概率也就变高了,所以很有必要进行扩容。

    那么这个扩容是怎么扩的呢?这里一般会有一个增长因子的概念,也叫作负载因子,简单点说就是已经被占的位置与总位置的一个百分比,比如一共十个位置,现在已经占了七个位置,就触发了扩容机制,因为它的增长因子是0.7,也就是达到了总位置的百分之七十就需要扩容。

    还拿HashMap来说,当它当前的容量占总容量的百分之七十五的时候就需要扩容了。

    而且这个扩容也不是简单的把数组扩大,而是新创建一个数组是原来的2倍,然后把原数组的所有Entry都重新Hash一遍放到新的数组。因为数组扩大了,所以一般哈希函数也会有变化,这里的Hash也就是把之前的数据通过新的哈希函数计算出新的位置来存放。

    展开全文
  • C++哈希表的实现

    2021-01-23 21:22:15
    C++哈希表的实现前言源码如下: 前言 本篇文章为笔者的读书笔记,未经允许请勿转载。如果对你有帮助记得点个赞(●’◡’●) 本文主要讲的哈希表的创建和使用, 源码如下: main #include <iostream> #...

    C++哈希表的实现


    前言

    本篇文章为笔者的读书笔记,未经允许请勿转载。如果对你有帮助记得点个赞(●’◡’●)
    本文主要讲的哈希表的创建和使用。哈希表的存储方式是不可逆,存储的value是经过哈希算法得到,所以只是获得存储中的value是毫无意义的,它只是密码经过哈希算法后得到的数值。


    源码如下:

    main

    #include <iostream>
    #include<string>
    #include"HashTable.hpp"
    using namespace std;
    void test()
    {
        //创建一个有15个节点的哈希表;
        HashTable<string> ht(15);
        
        bool is;
        cout << boolalpha;
        is = ht.insert(11, "A");
        cout << is << endl;
        is = ht.insert(22, "B");
        cout << is << endl;
        is = ht.insert(33, "C");
        cout << is << endl;
        is = ht.insert(44, "D");
        cout << is << endl;
        is = ht.insert(45, "D");
        cout << is << endl;
        is = ht.insert(55, "E");
        cout << is << endl;
        is = ht.insert(66, "F");
        cout << is << endl;
        is = ht.insert(77, "G");
        cout << is << endl;
        is = ht.insert(88, "H");
        cout << is << endl;
    
        cout << "-------------------------" << endl;
        ht.out();
        cout << "-------------------------" << endl;
    
        try
        {
            cout << ht.search(44) << endl;
        }
        catch (const char* str)
        {
            cout << str << endl;
        }
        ht.remove(45);
    
        cout << "-------------------------" << endl;
        ht.out();
        cout << "-------------------------" << endl;
    
        HashTable<string> ht1(ht);//调用拷贝构造
        try
        {
            cout << ht1.search(45) << endl;
        }
        catch (const char* str)
        {
            cout << str << endl;
        }
        cout << "-------------------------" << endl;
        ht1.out();
    
    }
    int main()
    {
        test();
        system("pause");
        return 0;
    }
    测试结果:
    true
    true
    true
    true
    true
    true
    true
    true
    true
    -------------------------
    [0]->nil
    [1]->(11:A)->(55:E)->nil
    [2]->nil
    [3]->nil
    [4]->nil
    [5]->nil
    [6]->nil
    [7]->(88:H)->nil
    [8]->(44:D)->nil
    [9]->(45:D)->nil
    [10]->nil
    [11]->(77:G)->nil
    [12]->(66:F)->nil
    [13]->(22:B)->(33:C)->nil
    [14]->nil
    -------------------------
    D//查询的数据
    -------------------------
    [0]->nil
    [1]->(11:A)->(55:E)->nil
    [2]->nil
    [3]->nil
    [4]->nil
    [5]->nil
    [6]->nil
    [7]->(88:H)->nil
    [8]->(44:D)->nil
    [9]->nil
    [10]->nil
    [11]->(77:G)->nil
    [12]->(66:F)->nil
    [13]->(22:B)->(33:C)->nil
    [14]->nil
    -------------------------
    没有这个数据//删除的数据
    -------------------------
    [0]->nil
    [1]->(11:A)->(55:E)->nil
    [2]->nil
    [3]->nil
    [4]->nil
    [5]->nil
    [6]->nil
    [7]->(88:H)->nil
    [8]->(44:D)->nil
    [9]->nil
    [10]->nil
    [11]->(77:G)->nil
    [12]->(66:F)->nil
    [13]->(22:B)->(33:C)->nil
    [14]->nil
    

    HashTable.hpp

    #pragma once
    #include<list>
    #include<utility>//pair
    template <class T>
    class HashTable
    {
    	public:
    		HashTable(int len):length(len),count(0) 
    		{
    			data = new hash_table[length]();//堆内存
    			//hash_table data[length]();栈内存
    
    		}
    		//拷贝构造
    		HashTable(const HashTable& ht):length(ht.length)
    		{
    			this->data = new hash_table[length]();
    			for (int i = 0; i < length; i++)
    			{
    				this->data[i] = ht.data[i];
    			}
    		}
    		~HashTable()
    		{
    			if (data)
    			{
    				delete[] data;
    				data = nullptr;
    			}
    		}
    		//插入数据
    		bool insert(int key, T val)
    		{
    			//通过hash运算再求余的方法插入位置,也可以用其他办法,自由发挥。
    			int base = hash(key) % length;
    			for (auto e:data[base])
    			{
    				if (e.first == key)
    				{
    					return false;
    				}
    			}
    			//数组里面的每一个元素都是一个list,二list里面的每一个元素是pair。
    			data[base].push_back({ key,val });
    			return true;
    		}
    		//查找数据
    		T search(int key)
    		{
    			int base = hash(key) % length;
    			for (auto e : data[base])
    			{
    				if (e.first == key)
    				{
    					return e.second;
    				}
    			}
    			throw "没有这个数据";
    		}
    		//删除数据
    		bool remove(int key)
    		{
    			int base = hash(key) % length;
    			for (auto it = data[base].begin(); it != data[base].end(); it++)
    			{
    				if (it->first == key)
    				{
    					data[base].erase(it);
    					return true;
    				}
    			}
    			return false;
    		}
    		//输出
    		void out()
    		{
    			for (int i = 0; i < length; i++)
    			{
    				std::cout << "[" << i << "]" << "->";
    				for (const auto& e : data[i])
    				{
    					std::cout <<"("<< e.first << ":" << e.second <<")"<< "->";
    				}
    				std::cout << "nil\n";
    			}
    		}
    private:
    	using hash_table = std::list<std::pair<int, T>>;
    	int length = 0;
    	int count = 0;
    	hash_table * data=nullptr;
    	//计算hash值的函数,对于频繁访问的hash函数可以用inline来使用更少的栈内存
    	inline int hash(int key)
    	{	
    		return key^10;
    	}
    };
    

    哈希表的实现原理不懂的可以参考一下
    可视化哈希表

    展开全文
  • C++ 哈希表的原理

    2021-01-15 15:01:56
    Hash也称为散列、哈希。 其基本的原理就是把任意长度的输入、通过Hash算法变成固定长度的输出。 这个映射的规则就是对应的Hash算法,而原始数据映射后的二进制串就是哈希值 比如常用加密方式:MD5和SHA都是Hash算法...
  • C++ 哈希表 排序整数

    2020-03-21 11:44:48
    #include<stdio.h> int main() { int random[10] = { 999,1,444,7,20,9,1,3,7,7 }; int hasp_map[1000] = { 0 }; for (int i = 0;... sizeof(random) / sizeof(random[0]);... hasp_map[random[...
  • C++哈希表用法

    千次阅读 2019-08-31 11:08:18
    hash用法,记得几个关键的, 引入 #include 定义 unordered_map, string> unomap; 引入的时候可以定义初始化,例如 unordered_map,string> unomap ={{1,"dd"},{2,"ssss"}}; 打印查找: ...
  • 哈希表的构造 哈希冲突的产生 解决哈希冲突的方法及代码实现 一.哈希的引入及概念 引入:当在顺序结构(如数组)或者平衡树(平衡二叉树)中查找一个元素时,必须要经过多次与内部元素进行比较的过程,顺序结构的查找...
  • C++ 哈希表

    2016-06-09 14:09:10
    #include #include #include #include #include using namespace std; templatetypename T> class HashEntry { public: int hash; string key; T value; HashEntryT> * next;... HashEntry
  • C++哈希表的原理和使用

    千次阅读 2020-08-18 14:48:02
    目录1、概念2、散列表的构造方法2.1、直接定址法 ...采用散列技术将记录存储在一块存储空间中,这块连续空间称为散列表或哈希表(Hash-Table)。 2、散列表的构造方法 2.1、直接定址法 直接定址法使用下
  • C++哈希表使用的好文章-Hash_Map

    热门讨论 2010-05-17 12:38:24
    hash_map基于hash table(哈希表)。 哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。然而在当前可利用内存越来越多的情况下,用空间换时间...
  • C++标准库中使用的unordered_map底层实现是哈希表,关于哈希表的一些基础知识,我看了公众号代码随想录里面的推文:《关于哈希表,你该了解这些!》,有了基本的认识。 哈希表是什么:哈希表是根据关键码的值而直接...
  • 1、哈希表不同于红黑树, 哈希表它的查找效率是o(1)、一个常数的效率。 虽然红黑树是o(logn), 很高的效率, 但不及它。 2、哈希表遍历的元素是无序的, 红黑树有序的。 这也决定他们实现的容器是何性质。 关于哈希表...
  • C++哈希表实现.zip

    2021-08-20 14:55:54
    C++实现哈希表
  • 数据结构中的哈希表问题,用C++编写的源代码
  • 利用C++哈希表的方法实现电话号码查询系统 如何运用哈希表的算法 深刻理解哈希表 利用C++哈希表的方法实现电话号码查询系统 如何运用哈希表的算法 深刻理解哈希表
  • 哈希表查找

    2017-04-27 20:54:24
    对于哈希表的查找一些简介
  • 哈希表(带template)

    2019-08-17 09:10:35
    哈希表的实现(注:计算对应变量的哈希值需要重载hashTable::hash_val函数),参考实现如下 #include #include using namespace std; /*注:functional里面定义了求哈希值的函数,这里的函数可以不用了*/ namespace ...
  • 哈希表的实现

    2014-07-06 11:20:15
    C++实现简单的哈希表,插入,查找,销毁。
  • 实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是:据说现在的QQ号码已经有10位数了。 输入格式: 输入首先给出一个正整数N(≤10​5​​),随后给出N行指令。每行指令的格式为:“命令...QQ号码为一个不超...
  • 随着C++0x标准的确立,C++的标准库中也终于有了hash table这个东西。 很久以来,STL中都只提供作为存放对应关系的容器,内部通常用红黑树实现,据说原因是二叉平衡树(如红黑树)的各种操作,插入、删除、查找等,都...
  • C++库之哈希表

    2021-09-02 17:23:04
    C++标准库中有哈希表,直接调用即可,包括哦unordered_map和unordered_set,使用之前需要引用头文件 #include <unordered_map> #include <unordered_set> 分别介绍一下unordered_map和unordered_set...
  • 哈希表C++实现

    2014-12-28 17:54:50
    哈希表c++实现,数据结构课程资源,课上独立完成,供大家借鉴
  • 针对本班的人名设计一个杂凑,数据的长度为50~80个记录;分析平均查找长度,完成相应的建表和查表程序,设计直观的界面显示杂凑的内容。 基本要求: 人名用汉语拼音表示,例如“苏志勇”表示为“su zhiyong”...
  • C++STL之哈希表

    千次阅读 2021-01-01 22:17:16
    C++ STL中,哈希表对应的容器是unordered_map(since C++ 11)。根据 C++ 11 标准的推荐,用unordered_map代替hash_map。 哈希表 先来回顾一下数据结构中哈希表相关的知识。 哈希表是根据关键码值(key value)而...
  • 使用map map是STL的一个关联容器,它提供一对一的hash。 第一个可以称为关键字(key),每个关键字只能在...比如需要组合的比较数组中的两个数据时,用哈希表可以将遍历过得数据存下来节省遍历搜索的时间 例题如下...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 53,579
精华内容 21,431
关键字:

c++哈希表

c++ 订阅