闭散列

来源:互联网 发布:怎么看淘宝自然流量 编辑:程序博客网 时间:2024/05/18 13:44
 
#include <iostream>#include <vector>#include <string>#include <utility>using namespace std;/*********************************************** 闭散列 *************************************/template <typename T, typename H>class chash{public://迭代器定义class iterator{public:iterator() {}iterator(chash<T, H> *tab, int p): htab(tab), bkt(p) {}T& operator*() {return htab->ht[bkt];}bool operator==(const iterator& rhs) {return bkt == rhs.bkt;}bool operator!=(const iterator& rhs) {return bkt != rhs.bkt;}iterator& operator++(){do ++ bkt;while (bkt < htab->bsize && htab->mark[bkt]);return *this;}iterator operator++(int){iterator tmp = *this;do ++ bkt; while (bkt < htab->bsize && htab->mark[bkt]);return tmp;}private:chash<T, H> *htab;//闭散列表int bkt;//桶地址};chash(int n, const H& h = H());int size() const {return hsize;}bool empty() const {return hsize == 0;}iterator find(const T& x);iterator begin();iterator end();pair<iterator, bool> insert(const T& x);void erase(const T& x);private:vector<T> ht;//桶向量vector<int> mark;//单元占用情况, 0表示桶单元ht[k]已被占用, 1表示空桶, 2表示曾被占用,但其中元素已删除int bsize;//桶向量大小int hsize;//元素个数H hf;//散列函数int match(const T& x)const;//返回元素x在桶向量中的位置int c(int i) const {return i;}//探测函数};template <typename T, typename H>chash<T, H>::chash(int n, const H& h): ht(n), mark(n, 1), bsize(n), hsize(0), hf(h) {}template <typename T, typename H>typename chash<T, H>::iterator chash<T, H>::begin(){int i = 0;while (i < bsize && mark[i]) ++i;return iterator(this, i); }template <typename T, typename H>typename chash<T, H>::iterator chash<T, H>::end(){return iterator(this, bsize);}template <typename T, typename H>int chash<T, H>::match(const T& x) const{int j = (int)(hf(x) % bsize);for (int i = 0; i < bsize; ++i){int k = (j + c(i)) % bsize;if (mark[k] == 1)  break;else if (mark[k] == 0 && ht[k] == x) return k;}return bsize;}template <typename T, typename H>typename chash<T, H>::iterator chash<T, H>::find(const T& x){int pos = match(x);return iterator(this, pos);}template <typename T, typename H>pair<typename chash<T, H>::iterator, bool> chash<T, H>::insert(const T& x){iterator it = find(x);if (it != end())//元素已经存在{return pair<iterator, bool>(it, false);}//寻找可用空间int k, i;int j = (int)(hf(x) % bsize);for (i = 0; i < bsize; ++i){k = (j + c(i)) % bsize;if (mark[k]) break;}if (i == bsize)  //没有可用空间{//no_mem();return pair<iterator, bool>(end(), false);}ht[k] = x;mark[k] = 0;++ hsize;return pair<iterator, bool>(iterator(this, k), true);}/*template <typename T, typename H>void chash<T, H>::erase(const T& x)//存在不足, 若执行了大量元素删除操作后查询的速度会变慢{int i = match(x);if (i < bsize) mark[i] = 2;-- hsize;}*/template <typename T, typename H>void chash<T, H>::erase(const T& x){int j, i = match(x);if (i < bsize){while (true){mark[i] = 1;for (j = (i+1) % bsize; mark[j] == 0; j = (j+1) % bsize){int h = int(hf(ht[j]) % bsize);if ((h <= i && i < j) || (i < j && j < h) || (j < h && h <= j)) break;}if (mark[j]) break;ht[i] = ht[j];mark[i] = mark[j];i = j;}-- hsize;}}/*********************************************** end 闭散列 *************************************/int hash1(const string& x)//散列函数{int hashval = 0;for(size_t i = 0; i < x.length(); ++i)hashval += x[i];return hashval % 100;}int main(void){typedef int (*hfunc)(const string&);chash<string, hfunc> ha(6, hash1);ha.insert("aa");ha.insert("bb");ha.insert("cc");ha.insert("dd");ha.insert("ee");ha.insert("ff");cout << ha.size() << endl;ha.erase("aa");ha.erase("bb");ha.erase("cc");ha.erase("dd");ha.erase("ee");cout << ha.size() << endl;chash<string, hfunc>::iterator it = ha.begin();while (it != ha.end()){cout << *it << "\t";++ it;}cout << endl;system("pause");return 0;}

原创粉丝点击