散列数据结构C++描述
来源:互联网 发布:地理数据名词解释 编辑:程序博客网 时间:2024/05/15 17:42
本文进行两种散列的实现——线性开型寻址散列,链表散列
散列表——一种动态集合结构,它仅支持Insert,Search和Delete操作
基本规则:关键字key,index=fun(key),T[index]卫星数据,函数fun即散列函数。查找一个元素的期望时间为O(1)
直接寻址表:关键字全域比较小,使用数组完全存储,一一对应。Insert,Search和Delete操作都是O(1)
散列表:关键字全域较大,可能出现碰撞。
解决碰撞之方法:
1)找到合适的散列函数。精心选择散列函数,并且仍然要解决可能出现的碰撞,该方法不太彻底。
2)链接法(实现)
给定一个能存放n个元素、具有m个槽位的散列表T,定义T的装载因子a=n/m,即一个链中平均存储的元素数。
任何元素散列到m个槽中每一个的可能性是相同的,且与其他元素已被散列到什么位置上是独立无关的。
这称为简单一致散列。一次成功查找为O(1+a),a=n/m,插入删除O(1),注a(书中为阿尔法)
3)开放寻址方法(例如线性开行寻址散列)
所有的元素都存放在散列表中,没有链表(即没有元素存放在散列表外),装载因子不大于1。
插入一个元素是,可以连续的检查散列表的各项,直到找到一个空槽来放置待插入的关键字时为止。
设计散列函数(算法设计略)
启发式方法:乘法散列和除法散列
随机化方法:全域散列
线性开型寻址散列实现
对散列表元素的删除操作执行起来比较困难;但可以解决,方法是:
删除槽i时,在将槽i的中设置一个特定的值DELETED,而不用NIL。当然相应的Hash-Search和Hash-Insert都要配合修改。
这样查找时间不依赖于装载因子a了。因此,在必须删除关键字的应用中,往往采用链接法来解决碰撞。
以下实现的删除方法,是在下信手胡写,并不正确。
// file hash.h#ifndef HashTable_#define HashTable_#include <iostream>#include <stdlib.h>#include "xcept.h"using namespace std;template<class E, class K>class HashTable{ public: HashTable(int divisor = 11); ~HashTable() {delete [] ht; delete [] empty;} bool Search(const K& k, E& e) const; HashTable<E,K>& Insert(const E& e); HashTable<E,K>& Delete(E& e); void Output();// output the hash table private: int hSearch(const K& k) const; int D; // hash function divisor E *ht; // hash table array bool *empty; // 1D array};template<class E, class K>HashTable<E,K>::HashTable(int divisor){// Constructor. D = divisor; // allocate hash table arrays ht = new E [D]; empty = new bool [D]; // set all buckets to empty for (int i = 0; i < D; i++) empty[i] = true;}template<class E, class K>int HashTable<E,K>::hSearch(const K& k) const{// Search an open addressed table. // Return location of k if present. // Otherwise return insert point if there is space. int i = k % D; // home bucket int j = i; // start at home bucket do { if (empty[j] || ht[j] == k) return j; j = (j + 1) % D; // next bucket } while (j != i); // returned to home? return j; // table full}template<class E, class K>bool HashTable<E,K>::Search(const K& k, E& e) const{// Put element that matches k in e. // Return false if no match. int b = hSearch(k); if (empty[b] || ht[b] != k) return false; e = ht[b]; return true;}template<class E, class K>HashTable<E,K>& HashTable<E,K>::Insert(const E& e){// Hash table insert. K k = e; // extract key int b = hSearch(k); // check if insert is to be done if (empty[b]) {empty[b] = false; ht[b] = e; return *this;} // no insert, check if duplicate or full if (ht[b] == k) throw BadInput(); // duplicate throw NoMem(); // table full}template<class E, class K>HashTable<E,K>& HashTable<E,K>::Delete(E& e){// Hash table insert. K k = e; // extract key int b = hSearch(k); // check if insert is to be done if (empty[b]) { cout << "没有该元素。" << endl; return *this; } empty[b] = true; int count = 0; int index = b+1; while (index != b) { if (index >= D) index -= D; K key; if (!empty[index]) { key = ht[index]; if ((key % D) != index) count++; } index++; } cout << "count=" << count << endl; E *temp = new E[count]; index = b+1; int i = 0; while (index != b) { if (index >= D) index -= D; K key; if (!empty[index] && i < count) { key = ht[index]; if ((key % D) != index) { temp[i] = ht[index]; empty[index] = true; i++; } } index++; } for (i = 0;i < count;i++) Insert(temp[i]); delete[] temp; return *this;}template<class E, class K>void HashTable<E,K>::Output(){ for (int i = 0; i< D; i++) { if (empty[i]) cout << "empty" << endl; else cout << ht[i] << endl;}}#endifxcept.h文件
// exception classes for various error types#ifndef Xcept_#define Xcept_#include <new>// bad initializersclass BadInitializers { public: BadInitializers() {}};// insufficient memoryclass NoMem { public: NoMem() {}};// change new to throw NoMem instead of xallocvoid my_new_handler(){ throw NoMem();};//new_handler Old_Handler_ = set_new_handler(my_new_handler);//set_new_handler(my_new_handler);// improper array, find, insert, or delete index// or deletion from empty structureclass OutOfBounds { public: OutOfBounds() {}};// use when operands should have matching sizeclass SizeMismatch { public: SizeMismatch() {}};// use when zero was expectedclass MustBeZero { public: MustBeZero() {}};// use when zero was expectedclass BadInput { public: BadInput() {}};#endifhash.cpp测试实例
// test hash table with linear open addressing#include <iostream>#include "hash.h"class element { friend int main(void); public: operator long() const {return key;}// private: g++ has a problem with main a friend int data; long key;};int main(void){ HashTable<element, long> h(11); element e; e.key = 80; h.Insert(e); e.key = 40; h.Insert(e); e.key = 65; h.Insert(e); h.Output(); e.key = 58; h.Insert(e); e.key = 24; h.Insert(e); cout << ' ' << endl; h.Output(); e.key = 2; h.Insert(e); e.key = 13; h.Insert(e); e.key = 46; h.Insert(e); e.key = 16; h.Insert(e); e.key = 7; h.Insert(e); e.key = 21; h.Insert(e); cout << ' ' << endl; h.Output(); e.key = 99; try {h.Insert(e);} catch (NoMem) {cout << " No memory for 99" << endl;} cout << "delete 24" << endl; e.key = 24; h.Delete(e); h.Output(); cout << "delete 15,there is not the element" << endl; e.key = 15; h.Delete(e); h.Output(); e.key = 2; h.Delete(e); h.Output(); return 0;}makefile文件
hash:hash.o hash.o xcept.h g++ -o hash hash.ohash.o:hash.cpp hash.h xcept.h g++ -c hash.cpp hash.h xcept.h g++ -c hash.h g++ -c xcept.hclean: rm -f hash *.o *.gch
输出结果:
emptyemptyempty80emptyemptyempty40emptyempty65 emptyempty248058emptyempty40emptyempty65 72124805821340461665 No memory for 99delete 24count=721empty2805813464016765delete 15,there is not the element没有该元素。21empty2805813464016765count=621empty1380584616407empty65
链接法实现
- 散列数据结构C++描述
- 散列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 散列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 散列 - C语言实现(摘自数据结构与算法分析 C语言描述)
- 散列-分离链接法(数据结构与算法分析-C语言描述)
- 数据结构(C语言描述)
- 用C语言描述数据结构
- 用C语言描述数据结构
- 数据结构---图(C描述)
- 数据结构---图(C描述)
- 用C语言描述数据结构
- 数据结构(C语言描述)
- 《数据结构与算法C#语言描述》笔记10_散列和Hashtable类
- C/C++基础必备,数据结构描述必备
- 数据结构(C语言描述)读书笔记之栈
- 数据结构(C语言描述)读书笔记之队列
- 数据结构(C语言描述)读书笔记之堆
- 数据结构(C语言描述)读书笔记之排序
- C/C++/C#/Java程序员的Ruby第一天
- java split(".");注意事项
- SVN commit:remains in tree-conflict错误的解决办法
- SQL Server常用语法集
- ToolTip终极写法,气泡提示
- 散列数据结构C++描述
- 《深度探索C++对象模型》读书笔记(2)。
- 显示规格类别
- 天气预报代码
- 二分图最大匹配总结
- Android中Activity和view之间的关系
- 设计模式之(十九)中介者模式Mediator
- 【转】RedHat Linux AS5安装Oracle 10g 及常见问题
- Android 移动开发 关于LBS的一些认知 经纬度纠偏问题的研究