• 哈希表实现


    哈希表实现:

    使用BKDRHash作为基础的哈希函数,同时使用拉链法作为冲突处理方法,实现哈希表的插入和查找操作。

    哈希函数BKDRHash实现如下:

    1 //映射方法,BKDRHash方法
    2 static int32_t BKDRHash(const string& str){
    3     int32_t hash=0,seed = 131;
    4     for(uint32_t i=0;i<str.length();i++){
    5         hash = hash * seed + str[i];
    6     }
    7     return (hash & 0x7fffffff);
    8 }

    处理冲突的方法有拉链法,开放定址和再哈希法。各种冲突方法如何实现,可以自行查资料进行学习,这里不做详细介绍。另附一张图,说明拉链法(说明版权:来源小象学院huge的算法讲解PPT)。

    程序实现:

      1 /***************************************
      2 FileName :HashTable.cpp
      3 Author : godfrey
      4 CreatedTime : 2016/5/1
      5 ****************************************/
      6 #include <iostream>
      7 #include <cstring>
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 
     11 using namespace std;
     12 
     13 class hash_node{
     14 public:
     15     hash_node() {
     16         this->data = "";
     17         this->next = NULL;
     18     }
     19     ~hash_node() {}
     20     void SetData(string data){
     21         this->data = data;
     22     }
     23     string GetData(){
     24         return this->data;
     25     }
     26     void SetNext(hash_node* next){
     27         this->next = next;
     28     }
     29     hash_node* GetNext(){
     30         return this->next;
     31     }
     32 private:
     33     string data;
     34     hash_node* next;
     35 };
     36 
     37 class hash_table{
     38 public:
     39     hash_table(int32_t hash_table_len,int32_t node_pool_len){
     40         this->hash_table_len = hash_table_len;
     41         this->node_pool_len = node_pool_len;
     42         this->node_pool_cnt = 0;
     43         try{
     44             this->hash_table_main = new hash_node*[this->hash_table_len];
     45             memset(this->hash_table_main,0,sizeof(hash_node*)*(this->hash_table_len));
     46             this->hash_node_pool = new hash_node[this->node_pool_len];
     47         }catch(const bad_alloc & e){
     48             std::cerr<<"there is no more place"<<endl;
     49         }
     50     }
     51     ~hash_table(){
     52         delete[] this->hash_table_main;
     53         delete[] this->hash_node_pool;
     54     }
     55     //哈希表的插入操作,使用拉链法
     56     bool insert(string str,bool& Is_uniqe){
     57         if(true == this->search(str)){
     58             Is_uniqe = false;
     59             return true;
     60         }
     61         //拉链法插入
     62         hash_node* p;
     63         hash_node* q = this->GetNewNode();
     64         if(q == NULL) return false;
     65         int32_t index = this->GetHashIndex(str);
     66         p = this->hash_table_main[index];
     67         q->SetData(str);
     68         q->SetNext(p);
     69         this->hash_table_main[index] = q;
     70         Is_uniqe = true;
     71         return true;
     72     }
     73     //哈希表的查找操作
     74     bool search(string str){
     75         int32_t index = this->GetHashIndex(str);
     76         hash_node* p = this->hash_table_main[index];
     77         while(p){
     78             if(p->GetData()==str) return true;
     79             p = p->GetNext();
     80         }
     81         return false;
     82     }
     83 private:
     84     hash_node** hash_table_main;//哈希表的大小
     85     hash_node* hash_node_pool;//哈希表的内存池
     86 
     87     int32_t hash_table_len,node_pool_len,node_pool_cnt;
     88     //映射方法,BKDRHash方法
     89     static int32_t BKDRHash(const string& str){
     90         int32_t hash=0,seed = 131;
     91         for(uint32_t i=0;i<str.length();i++){
     92             hash = hash * seed + str[i];
     93         }
     94         return (hash & 0x7fffffff);
     95     }
     96     //获取哈希表中字符串相应的索引
     97     int32_t GetHashIndex(string& str){
     98         if(hash_table_len == 0) return 0;
     99         return (hash_table::BKDRHash(str)%this->hash_table_len);
    100     }
    101     //在内存池中获取新的节点内存
    102     hash_node* GetNewNode(){
    103         if(this->node_pool_cnt>=this->node_pool_len) return NULL;
    104         return &this->hash_node_pool[node_pool_cnt++];
    105     }
    106 };
    107 
    108 int main()
    109 {
    110     hash_table ht(100,1000);
    111     bool is_uniqe,flag;
    112     ht.insert("godfrey",is_uniqe);
    113     cout<<"ht.insert godfrey : "<<is_uniqe<<endl;
    114     ht.insert("good",is_uniqe);
    115     cout<<"ht.insert good : "<<is_uniqe<<endl;
    116     ht.insert("godfrey",is_uniqe);
    117     cout<<"ht.insert godfrey twice : "<<is_uniqe<<endl;
    118     flag = ht.search("godfrey");
    119     cout<<"ht.search godfrey : "<<flag<<endl;
    120     return 0;
    121 }

    运行结果:

    转载请注明出处:

    C++博客园:godfrey_88

    http://www.cnblogs.com/gaobaoru-articles/

    转载请注明出处: C++博客园:godfrey_88 http://www.cnblogs.com/gaobaoru-articles/
  • 相关阅读:
    【转载】Java系列笔记(3)
    CentOS 7下Samba服务器的安装与配置
    Linux常用目录结构
    Linux计划任务crontab
    转:Linux 双网卡配置两个IP同时只有一个会通的原因
    centos7中搭建ntp服务器
    centos7中使用vg方式扩充root分区
    ping命令脚本实现显示网络状态、学生姓名、学号
    centos中基于随机数,再加入班级学生姓名
    centos7 shell脚本实现随机数
  • 原文地址:https://www.cnblogs.com/gaobaoru-articles/p/5450310.html
Copyright © 2020-2023  润新知