(2011.08.18)散列表

来源:互联网 发布:在淘宝上怎么买到弓弩 编辑:程序博客网 时间:2024/05/21 18:38

    昨天看了数据结构中的散列的内容,将一些书上的代码敲了一下,加深记忆,当然,也对散列的大部分内容了解了一遍,知道它的原理大概是什么样的了。刚刚开始接触,看前几节的内容,还是很不理解这究竟是什么,散列函数用作什么用,后来,发觉,原来(只是个人理解)最大的作用是定位,找到相对应的位置,可以进行操作了,而,散列表也相当于是将一连串的类,用一个表放起来。

// 504 散列/** * 散列:是一种用于常数平均时间执行的插入、删除和查找的技术。 * 键(Key):查找一般是对项的某个部分(即数据成员)进行的。 * 散列函数:将每个键映射到0到TableSize - 1这个范围中的某个数,并将其放到适当的单元中。 * 冲突(collision):决定当两个键列到同一个值的时候。 * 分离链接法(separate chaining):将散列到同一个值的所有元素保留到第一个链表中。 * 可扩散列(extendible hashing):处理数据量太大以至于装不进主存的情况。 **/// 分离链接法 -- 缺点:给新单元分配地址需要时间,导致算法的速度有点慢。// ( 并非一个完整代码)template <typename HashedObj>class HashTable{public:// 散列大小一般设为素数explicit HashTable(int size = 101);bool contains(const HashedObj & x) const;void makeEmpty();void insert(const HashedObj & x);void remove(const HashedObj & x);private:vector < list<HashedObj> > theLists;// The array of Listsint currentSize;void rehash();int myhash( const HashedObj & x) const;};int hash(const string & key);int hash( int key);/*** A hash routine for string objects.*/int hash( const string & key, int tableSize){int hashVal = 0;for (int i = 0; i < key. length(); i++)hasVal = 37 * hashVal + key[i];hashVal %= tableSize;if (hashVal < 0)hashVal += tableSize;return hashVal;}int myhash(const HashedObj & x) const {int hashVal = hash(x);hashVal %= theLists.size();if (hashVal < 0)hashVal += theLists.size();return hashVal;}void makeEmpty(){for (int i = 0; i < theLists.size(); i++)theLists[i].clear();}bool contains(const HashedObj & x) const{const list<HashedObj> & whichList = theLists[myhash(x)];return find(whichList.begin(), whichList.end(), x) != whichList.end();}bool remove(const HashedObj & x){list <HashedObj> & whichList = theLists[myhash(x)];list<HashedObj>:: iterator itr = find(whichList.begin(), whichList.end(), x);if (itr == whichList.end())return false;whichList.erase(itr);--currentSize;return true;}bool insert (const HashedObj & x){list<HashedObj> & whichList = theLists[myhash(x)];if(find(whichList.begin(), whichList.end(), x) != whichList.end() )return false;whichList.push_back(x);if (++currentSize > theLists.size() )rehash();return true;}void rehash(){vector<list<HashedObj> > oldLists = theLists;// Create new double-sized, empty tabletheLists.resize(nextPrime( 2 * theLists.size() ) );for (int j = 0; j < theLists.size(); j++)theLists[j].clear();// copy table overcurrentSize = 0;for (int i = 0; i < oldLists.size(); ++i){list<HashedObj>::iterator itr = oldLists[i].begin();while( itr!= oldLists[i].end())insert(*itr++);}return;}// 使用探测策略的散列表的类接口template< typename HashedObj>class HashTable{public:explicit HashTable(int size = 101);bool contains(const HashedObj & x) const;void makeEmpty();bool insert( const HashedObj & x);bool remove(const HashedObj & x);enum EntryType {ACTIVE, EMPTY, DELETED);private:struct HashEntry{HashedObj element;EntryType info;HashEntry(const HashedObj & e = HashedObj(), EntryType i = EMPTY): element(e), info(i){}};vector<HashEntry>array;int currentSize;bool isActive(int currentPos) const;int findPos(const HashedObj & x)const;void rehash();int myhash(const HashedObj & x) const;};int hash( const string & key, int tableSize){int hashVal = 0;for (int i = 0; i < key.length(); i++)hashVal = 37 * hashVal + key[i];hashVal %= tableSize;if (hashVal < 0)hashVal += tableSize;return hashVal;}explicit HashTable(int size = 101): array(nextPrime(size)){ makeEmpty();}void makeEmpty(){currentSize = 0;for (int i = 0; i < array.size(); i++)array[i].info = EMPTY;}bool contains(const HashedObj & x) const{ return isActive(findPos(x) );}int findPos( const HashedObj & x) const {int offset = 1;int currentPos = myhash(x);while(array[currentPos].info != EMPTY && array[currentPos].element != x){currentPos += offset;// Compute ith probeoffset += 2;if (currentPos >= array.size())currentPos -= array.size();}return currentPos;}bool isActive( int currentPos) const {return array[currentPos].info == ACTIVE; }bool insert(const HashedObj & x){// Insert x as activeint currentPos = findPos(x);if (isActive(currentPos) )return false;array[currentPos] = HashEntry(x, ACTIVE);if ( ++currentSize > array.size() / 2)rehash();return true;}bool remove(const HashedObj & x){int currentPos = findPos(x);if (!is Active(currentPos) )return false;array[currentPos].info = DELETD;return true;}void rehash(){vector < HashEntry> oldArray = array;// create new double-sized, empty tablearray.resize(nextPrime(2 * oldArray.size() ) );for ( int i = 0; i < oldArray.size(); i++ )if (oldArray[i].info == ACTIVE)insert(oldArray[i].element);}


原创粉丝点击