散列函数与层级结构数据
来源:互联网 发布:linux vim 强制保存 编辑:程序博客网 时间:2024/05/22 12:23
近两天在温习数据结构时,对散列函数与树结构数据处理优化有些想法。
首先看看散列函数的定义:在数据元素的关键字与该元素的存储位置之间建立一种对应关系,将这种关系称为散列函数(hash function)。
例如,哈希表(Hash table,也叫散列表),就是采用散列函数将元素数据映射成数据或链表的存储位置实现的,HashMap类似,只是映射结果是key不是位置。
期待c++标准库直接支持hashtable/hashmap/hashset的容器。
1、深化树层级
场景设想,目前我们有组对象,他们都有一个唯一的编号,一个很大的编号,为了快速访问和定位,很容易设想std::map<long long key, T val>去装载他们。
但很显然易见的是当map大到一定程度时对效率影响还是挺大的,这是就需要层级结构处置他们,就可以结合散列函数做一个类似的map装载他们:
给出的示例代码:
template <class T>
class OBJMAP
{
public:
OBJMAP(){};
~OBJMAP(){};
void insert(long long key,T val)
{
data[hash(key)][key]=val;
};
T getVal(long long key)
{
std::map<long long,std::map<long long,T> >::iterator it = data.find(hash(key));
if(it != data.end()){
std::map<long long,T>::iterator it_obj = it->second.find(key);
if(it_obj != it->second.end())
{
return it_obj->second;
}
}
return T();
};
long long size()
{
long long ret = 0;
std::map<long long,std::map<long long,T> >::iterator it = data.begin();
while(it != data.end()){
ret += static_cast<long>(it->second.size());
it++;
}
return ret;
};
//其他函数类似
private:
long long hash(long long key)
{
//简单的散列表示,实际按需调整设定散列算法,例如前几位表示区域,中间几位表述类型,后面表示对象号等等
return static_cast<int>(key/PAGECOUNT);
};
private:
//
static const long long PAGECOUNT = 10000;
std::map<long long,std::map<long long,T> > data;
};
2、扁平化树层级
场景设想,有时候我们会遇到这样一种情况,我们要识别一个对象,首先需要找到他所在区域,再找到所在类型,再更具编号识别到对象,看起来应该是这样存储的:
std::map<int,std::map<int,std::map<int,T> > >,如果数据量不大,这种多层级的如果通过散列函数概念,建立区域、类型、编号到位置key一对一的映射关系[1],或者说区域、类型、编号组合成一个key 对象[2],就能将多层级简化
[2]示列代码:
class KeyObj
{
public:
KeyObj(int _domain,int _type, int _id)
: m_domain(_domain),m_type(_type),m_id(_id)
{
};
//
static int cmp_Key(const KeyObj &obj1, const KeyObj &obj2)
{
int diff = obj1.m_domain - obj2.m_domain;
if(diff!=0) return diff;
diff = obj1.m_type - obj2.m_type;
if(diff!=0) return diff;
diff = obj1.m_id - obj2.m_id;
if(diff!=0) return diff;
return 0;
};
int m_domain;
int m_type;
int m_id;
};
inline bool operator==(const KeyObj& obj1, const KeyObj& obj2) { return KeyObj::cmp_Key(obj1,obj2)==0 ; }
inline bool operator!=(const KeyObj& obj1, const KeyObj& obj2) { return KeyObj::cmp_Key(obj1,obj2)!=0 ; }
inline bool operator>=(const KeyObj& obj1, const KeyObj& obj2) { return KeyObj::cmp_Key(obj1,obj2)>=0 ; }
inline bool operator<=(const KeyObj& obj1, const KeyObj& obj2) { return KeyObj::cmp_Key(obj1,obj2)<=0 ; }
inline bool operator>(const KeyObj& obj1, const KeyObj& obj2) { return KeyObj::cmp_Key(obj1,obj2)>0 ; }
inline bool operator<(const KeyObj& obj1, const KeyObj& obj2) { return KeyObj::cmp_Key(obj1,obj2)<0 ; }
template <class T>
class MyObj
{
MyObj(){};
void insert(KeyObj key,T val)
{
data[key]=val;
};
void insert(int _domain,int _type, int _id,T val)
{
insert(KeyObj(_domain,_type,_id),val);
};
T getVal(KeyObj key)
{
std::map<KeyObj,T>::iterator it = data.find(key);
if(it != data.end()){
return it->second;
}
return T();
};
//其他函数类似实现
private:
std::map<KeyObj,T> data;//由于采用map,需要KeyObj实现map的key排序准则
};
散列表在实际应用场景要比这复杂很多,主要看其引入是否能降低访问复杂度、插入复杂度等,否则宁可不用。
- 散列函数与层级结构数据
- [数据库]数据库存储层级结构数据
- 数据在计算机中存储的物理结构有四种:顺序、链表、散列与索引
- 散列与Java Map结构分析
- HyperWorks 集成桌面环境下二次开发【三】----数据层级结构
- iOS开发笔记>> UIButton与UITableView的层级结构
- 数据存储结构---顺序 链式 索引 散列
- DOM文档层级结构
- 存储器的层级结构
- iOS层级结构
- 数据库层级结构实现
- 目录的层级结构
- 程序员的层级结构
- fhs文件系统层级结构
- 散列函数与散列表
- javascript 层级数据的递归遍历与节点插入
- 索引结构与散列技术 POWERBY CHenCHengNET
- 散列hash算法与结构学习笔记
- cas加入验证码以及强制密码到期修改流程
- source inisight无法跳转
- BIEE 11g catalog自动复制
- 非SSL协议 CAS服务端部署及客户端配置
- Oracle基本语法之DML(二)
- 散列函数与层级结构数据
- leetcode 494
- 服务端改造(登录页及登录方式的自定义)
- hdu 1003 Max Sum (dp)
- 二进制中1的个数
- 2017年中国国际信息通信展览会
- RecyclerView头布局添加
- 卷积神经网络入门一种全卷积神经网络(LeNet),从左至右依次为卷积→子采样→卷积→子采样→全连接→全连接→高斯连接测试 最后,为了检验 CNN 能否工作,我们准备不同的另一组图片与标记集(不能在训练
- 二叉树的前序,后序,中序,层次遍历