前言
本篇文章为笔者的读书笔记,未经允许请勿转载。如果对你有帮助记得点个赞(●’◡’●)
本文主要讲的哈希表的创建和使用。
哈希表是一种数据结构,用于存储和检索数据。它通过使用哈希函数将键值对映射到存储桶中,从而实现快速的数据访问。哈希表的作用是提供高效的查找、插入和删除操作。它的时间复杂度是常数级别的,因此在大量数据中能够快速定位需要的数据。哈希表的缺点是数组创建后难于扩展,当数组负载因子过大时就会扩容,性能会受到很大的影响。
源码如下:
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;
}
};
哈希表的实现原理不懂的可以参考一下
可视化哈希表