数据结构-HashTable的简单

来源:互联网 发布:c语言汉诺塔游戏 编辑:程序博客网 时间:2024/05/19 03:28

最近复习数据结构相关的知识,自己实现一个简单的散列表:

散列表的总结

  1. 散列表是键与值得对应,最主要的优点就是查找的速度很快。
  2. 通过一个hash函数f(k),将key计算得到一个唯一的hash值,然后通过这hash值作为数组的下标来访问元素。
  3. 如果数据量很多或者hash函数选择不当,那么很可能多个多个key计算出来对应了一个数组的下标,这个称为冲突,解决冲突的方法从两个方面入手
    1. 哈希函数:哈希函数的公式比较多,最简单的应该就是取模运算了
    2. 冲突解决:如果真的发生了,那么可以使用额外的步骤来存储这些元素,我这里使用了链表来存储这些元素
  4. 一个简单的示意图,左边代表了一个数组,数组元素指向一个链表,这个链表保存了hash值相同的元素。

  5. 下面是我自己的简单的一个实现,一些优化
    1. Hash函数
    2. 可以实时的调整hash表的大小的,比如当前存储的元素与最大的元素比例到达80%,那么此时可以扩大从而减小冲突
    3. 如果模板的参数是一个引用类型,编译不过
  6. // hashtable.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <Windows.h>#include <iostream>using namespace std;typedef struct _hash_table{} hash_table_t;template <typename K, typename V>class hashtable{private:typedefstruct _hash_entry{K key;V value;struct _hash_entry *next;} hash_entry_t;typedef struct _iterator_data{hash_entry_t *cur_entry;hash_entry_t *next_entry;UINTcur_index;boolit_started;} iterator_data_t;hash_entry_t **table;UINT max_number;UINT persist_number;UINT cur_entry;iterator_data_t it_data;UINT get_hashkey(K &key);public:hashtable(UINT max_number = 10, UINT(*hash_key)(K &key) = NULL);~hashtable();bool insert(K key, V value);bool lookup(K key, V &value);bool remove(K key, V &value);void remove_all();bool start_iterator();bool has_next();bool next_entry(K &key, V &value);bool end_iterator();UINT(*hash_key)(K &key);};template<typename K, typename V>hashtable<K, V>::hashtable(UINT max_number, UINT(*hash_key)(K &key)){this->hash_key = hash_key;this->max_number = max_number;persist_number = 0;cur_entry = 0;table = new hash_entry_t*[this->max_number];memset(table, 0x00, sizeof(hash_entry_t*) * this->max_number);memset(&it_data, 0x00, sizeof(it_data));}template<typename K, typename V>hashtable<K, V>::~hashtable(){remove_all();delete table;table = NULL;}template<typename K, typename V>UINT hashtable<K, V>::get_hashkey(K &key){if (hash_key){return hash_key(key);}else{UINT val = (UINT)key;return val % max_number;}}template<typename K, typename V>bool hashtable<K, V>::insert(K key, V value){UINT index = get_hashkey(key);hash_entry_t *entry = table[index];hash_entry_t *prev_entry = NULL;do{if (entry){if (entry->key == key){return false;}else{prev_entry = entry;entry = entry->next;}}else{entry = new hash_entry_t;entry->key = key;entry->value = value;entry->next = NULL;if (prev_entry){prev_entry->next = entry;}else{table[index] = entry;}break;}} while (TRUE);return true;}template<typename K, typename V>bool hashtable<K, V>::lookup(K key, V & value){UINT index = get_hashkey(key);if (table[index]){hash_entry_t *entry = table[index];while (entry){if (entry->key == key){value = entry->value;return true;}entry = entry->next;}}return false;}template<typename K, typename V>bool hashtable<K, V>::remove(K key, V & value){UINT index = get_hashkey(key);if (table[index]){hash_entry_t *entry = table[index];hash_entry_t *prev_entry = NULL;while (entry){if (entry->key == key){value = entry->value;if (prev_entry){prev_entry->next = entry->next;delete entry;entry = NULL;}else{table[index] = NULL;delete entry;entry = NULL;}return true;}prev_entry = entry;entry = entry->next;}}return false;}template<typename K, typename V>void hashtable<K, V>::remove_all(){for (UINT index = 0; index < max_number; index++){if (table[index]){hash_entry_t *entry = table[index];while (entry){hash_entry_t *entry_temp = entry;entry = entry->next;delete entry_temp;entry_temp = NULL;}table[index] = NULL;}}}template<typename K, typename V>bool hashtable<K, V>::start_iterator(){if (it_data.it_started){return false;}it_data.cur_entry = NULL;it_data.cur_index = -1;it_data.it_started = true;return true;}template<typename K, typename V>bool hashtable<K, V>::has_next(){if (it_data.cur_entry){it_data.cur_entry = it_data.cur_entry->next;if (it_data.cur_entry){return true;}}for (it_data.cur_index++; it_data.cur_index < max_number; it_data.cur_index++){it_data.cur_entry = table[it_data.cur_index];if (it_data.cur_entry){return true;}}return false;}template<typename K, typename V>bool hashtable<K, V>::next_entry(K &key, V &value){if (it_data.cur_entry){key = it_data.cur_entry->key;value = it_data.cur_entry->value;return true;}return false;}template<typename K, typename V>bool hashtable<K, V>::end_iterator(){if (!it_data.it_started){return false;}it_data.cur_entry = NULL;it_data.cur_index = -1;it_data.it_started = false;return true;}int main(){hashtable<int, int> table;for (int i = 0; i < 200; i++){table.insert(i, i * 20);}for (int i = 200; i >= 0; i--){int value;if (table.lookup(i, value)){cout << "Lookup:" << i << " = " << value << endl;}else{cout << "Lookup " << i << " failed" << endl;}}int value;table.remove(10, value);table.remove(50, value);for (int i = 200; i >= 0; i--){int value;if (table.lookup(i, value)){cout << "Lookup:" << i << " = " << value << endl;}else{cout << "Lookup " << i << " failed" << endl;}}table.start_iterator();while (table.has_next()){int key, value;table.next_entry(key, value);cout << key << " : " << value << endl;}table.end_iterator();return 0;}


原创粉丝点击