重复发明轮子 自己实现哈希表。
Posted bywayboy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重复发明轮子 自己实现哈希表。相关的知识,希望对你有一定的参考价值。
首先想用汇编写的。但写到最后晕头转向。没办法。先用C++验证一遍自己的思路吧。代码如下。
- CHashMap::CHashMap()
- {
- m_size = 100;
- m_count = 0;
- m_nodes = (PCNODE)malloc(sizeof(CNODE)*100);
- ZeroMemory(m_nodes,sizeof(CNODE)*100);
- }
- CHashMap::~CHashMap()
- {
- for(int i=0;i<m_size;i++)
- {
- PCNODE cur_node = m_nodes+i;
- if(cur_node->left)
- _Del_X(cur_node->left);
- if(cur_node->right)
- _Del_X(cur_node->right);
- }
- free(m_nodes);
- }
- BOOL CHashMap::Set(DWORD key,DWORD value)
- {
- if(m_count/m_size>=0.72)
- {
- // 重建哈希表 尺寸是原来的哈希表的双倍。
- DWORD new_size = m_size*2;
- PCNODE new_nodes = (PCNODE)malloc(sizeof(CNODE)*new_size);
- ZeroMemory(new_nodes,sizeof(CNODE)*new_size);
- for(int i=0;i<m_size;i++)
- {
- PCNODE cur_node = m_nodes+i;
- if(cur_node->key)
- {
- //添加当前节点。
- PCNODE add_node = _GetAddress_X(new_nodes,new_size,cur_node->key);
- if(add_node) add_node->value=cur_node->value;
- //遍历子节点,并且要删除旧的。
- if(cur_node->right)
- _SetAndDel_X(new_nodes,new_size,cur_node->right);
- if(cur_node->left)
- _SetAndDel_X(new_nodes,new_size,cur_node->left);
- }
- }
- //删除旧的.
- free(m_nodes);
- m_nodes = new_nodes;
- m_size = new_size;
- }
- PCNODE node;
- if(node= _GetAddress_X(m_nodes,m_size,key))
- {
- node->value=value;
- m_count++;
- return TRUE;
- }
- return FALSE;
- }
- DWORD CHashMap::Get(DWORD key)
- {
- // 先定位到数据。比较键值,寻找节点。最后返回需要的值。
- DWORD pos= key % m_size;
- PCNODE node=m_nodes+pos;
- while(node){
- if(key>node->key)
- node = node->right;
- else if(key<node->key)
- node = node->left;
- else
- return node->value;
- }
- return NULL;
- }
- BOOL CHashMap::Exists(DWORD key)
- {
- DWORD pos= key % m_size;
- PCNODE node=m_nodes+pos;
- while(node){
- if(key>node->key)
- node = node->right;
- else if(key<node->key)
- return TRUE;
- else
- return node->value;
- }
- return FALSE;
- }
- BOOL CHashMap::Del(DWORD key)
- {
- DWORD pos= key % m_size;
- PCNODE par_node = NULL,cur_node,node=m_nodes+pos;
- if(NULL == node->key) return FALSE;
- while(node){
- if(key>node->key){
- par_node = node;
- node = node->right;
- }else if(key<node->key){
- par_node = node;
- node = node->left;
- }else{
- cur_node = node;
- break;
- }
- }
- if(!node) return FALSE; //没有找到 返回了
- if(!par_node) //根节点的情况
- {
- if (cur_node->right)
- {
- PCNODE left_node = cur_node->left;
- *cur_node = *cur_node->right;
- if(left_node){
- //挂到最左边去。
- while(cur_node->left){
- cur_node = cur_node->left;
- }
- cur_node->left = left_node;
- }
- }else if(cur_node->left)
- {
- //没有右边节点的情况.
- *cur_node = *cur_node->left;
- }else{
- //啥也没有的情况
- cur_node->value = cur_node->key = 0;
- cur_node->left=cur_node->right=NULL;
- }
- return TRUE;
- }
- /* 不是根节点的情况 需要 释放 cur_node*/
- if(cur_node->right){
- par_node->right=cur_node->right;
- //左边的节点挂到右边的最左边。
- if(cur_node->left){
- node = cur_node;
- while(node->left){node=node->left;}
- node->left=cur_node->left;
- }
- }else if(cur_node->left){
- //不存在右边的情况。
- par_node->left=cur_node->left;
- }else
- {
- if(par_node->left == cur_node)
- par_node->left=NULL;
- else
- par_node->right=NULL;
- }
- free(cur_node);
- return TRUE;
- }
- // 这是一个静态方法,复制新的节点,并删除旧的节点。
- void CHashMap::_SetAndDel_X(PCNODE arg_nodes,DWORD arg_size,PCNODE arg_node)
- {
- PCNODE add_node = _GetAddress_X(arg_nodes,arg_size,arg_node->key);
- if(add_node) add_node->value=arg_node->value;
- if(arg_node->right)
- _SetAndDel_X(arg_nodes,arg_size,arg_node->right);
- if(arg_node->left)
- _SetAndDel_X(arg_nodes,arg_size,arg_node->left);
- free(arg_node);
- }
- void CHashMap::_Del_X(PCNODE arg_node)
- {
- if(arg_node->right)
- _Del_X(arg_node);
- if(arg_node->left)
- _Del_X(arg_node);
- free(arg_node);
- }
- /*
- 如果相同键值的数据存在,会返回空。
- 这个方法是静态的。
- 如果存在,它会给我一个空间。如果不存在。它会分配好一个新的地址。
- */
- PCNODE CHashMap::_GetAddress_X(PCNODE arg_node,DWORD arg_size,DWORD key)
- {
- DWORD pos= key % arg_size;
- PCNODE t_node,node=arg_node+pos;
- if(node->key==0){
- node->key = key;
- return node;
- }
- while (node)
- {
- t_node = node;
- if(key>node->key)
- node=node->right;
- else if(key == node->key)
- return NULL;
- else
- node=node->left;
- }
- node = (PCNODE)malloc(sizeof(CNODE));
- node->key=key;node->left=node->right = NULL;
- if(key>t_node->key)
- t_node->right = node;
- else
- t_node->left = node;
- return node;
- }
头文件:
- class CHashMap
- {
- public:
- CHashMap();
- BOOL Set(DWORD key,DWORD value);//设置数据
- DWORD Size(){return m_size;} //取容量尺寸
- DWORD Count(){return m_count;} //取数据数目
- DWORD Get(DWORD key); //取数据
- BOOL Del(DWORD key); //删除数据
- BOOL Exists(DWORD key); //数据是否存在
- virtual ~CHashMap();
- private:
- static PCNODE _GetAddress_X(PCNODE arg_node,DWORD arg_size,DWORD key);
- static void _SetAndDel_X(PCNODE arg_nodes,DWORD arg_size,PCNODE arg_node);
- void _Del_X(PCNODE arg_node);
- protected:
- DWORD m_size;
- DWORD m_count;
- PCNODE m_nodes;
- };
以上是关于重复发明轮子 自己实现哈希表。的主要内容,如果未能解决你的问题,请参考以下文章