Hash_Table(散列表)

以下代码仅在 g++ 3.4.2中编译通过,令人惊奇的是VC 2005竟然编译出错,看来以后用VC 2005还得小心才行。

 

// 结点类型
template  < typename T, typename Tar >
struct  node
{
    T data;
    Tar value;
    node
* next;
    
//初始化为空
    node()
        : value(
0), next(NULL)
    
{}
}
;
// Hash表
// 第一个类型参数的类型可以是:int, long, char, string
// 第二个类型参数的类型可以是:int, bool, char
// 此Hash表支持的操作有:
// insert(T x):将类型为T的元素插入hash表中,如果已存在则直接退出
// search(T x):查找是否存在值为x的元素(返回bool型)
// remove(T x):将值为x的元素从表中删除
// 对于[]的重载:返回value域的引用
template  < typename T, typename Tar >
class  Hash_Table
{
private:
    
static const int size = 350899;    //尺寸
    node<T, Tar> *t;
    
//直接hash
    inline int hash(int n)
    
{
        
return n % size;
    }

    
//用于串的elfhash
    inline int hash(const char* key)
    
{
        unsigned 
int h = 0;
        
while (*key)
        
{
            h 
= (h << 4+ *key++;
            unsigned 
int g = h & 0xF0000000L;
            
if (g)
                h 
^= g >> 24;
            h 
&= ~g;
        }

        
return h % size;
    }

    
//string的elfhash
    inline int hash(const string& str)
    
{
        
return hash(str.c_str());
    }

public:
    Hash_Table()
        : t(
new node<T, Tar>[size])
    
{}
    
//插入一个元素
    inline void insert(const T& item)
    
{
        
if (search(item))    //如果已存在就退出
            return;
        
int key = hash(item);
        
if (!t[key].value)    //空的
        {
            t[key].value 
= 1;
            t[key].data 
= item;
            t[key].next 
= NULL;
        }

        
else    //非空,insert item at the head of the list
        {
            node
<T, Tar>* tmp = new node<T, Tar>;
            tmp
->value = t[key].value;
            tmp
->data = t[key].data;
            tmp
->next = t[key].next;
            t[key].value 
= 1;
            t[key].data 
= item;
            t[key].next 
= tmp;
        }

    }

    inline 
bool search(const T& item)
    
{
        
int key = hash(item);
        
if (!t[key].value) //空的
            return false;
        node
<T, Tar>* tmp = &t[key];
        
while (tmp->next != NULL && tmp->data != item)
            tmp 
= tmp->next;
        
return (tmp->data == item);
    }

    inline 
void remove(const T& item)
    
{
        
int key = hash(item);
        
if (t[key].value && t[key].data == item)    //不空,并且要删的是第一个
        {
            
if (t[key].next != NULL)
            
{
                node
<T, Tar>* tmp = t[key].next;
                t[key].data 
= tmp->data;
                t[key].next 
= tmp->next;
                delete tmp;
            }

            
else
                t[key].value 
= 0;
        }

        
else
        
{
            
if (t[key].value)    //不空才执行
            {
                node
<T, Tar>* tmp = &t[key];
                
while (tmp->next != NULL && tmp->next->data != item)
                    tmp 
= tmp->next;
                
if (tmp->next != NULL)
                
{
                    node
<T, Tar>* p = tmp->next;
                    tmp
->next = p->next;
                    delete p;
                }

            }

        }

    }

    Tar
& operator[](const T& item)
    
{
        
int key = hash(item);
        node
<T, Tar>* tmp = &t[key];
        
while (tmp->next != NULL && tmp->data != item)
            tmp 
= tmp->next;
        tmp
->data = item;
        
return tmp->value;
    }

}
;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值