Title: STL系列之九 探索hash_set
Author: MoreWindows
Blog: http://blog.csdn.net/MoreWindows
E-mail: morewindows@126.com
KeyWord: C++ STL set hash_set 哈希表 链地址法
本文将着重探索hash_set比set快速高效的原因,阅读本文前,推荐先阅读本文的姊妹篇《STL系列之六 set与hash_set》
一.hash_set之基石——哈希表
hash_set的底层数据结构是哈希表,因此要深入了解hash_set,必须先分析哈希表。哈希表是根据关键码值(Key-Value)而直接进行访问的数据结构,它用哈希函数处理数据得到关键码值,关键码值对应表中一个特定位置再由应该位置来访问记录,这样可以在时间复杂性度为O(1)内访问到数据。但是很有可能出现多个数据经哈希函数处理后得到同一个关键码——这就产生了冲突,解决冲突的方法也有很多,各大数据结构教材及考研辅导书上都会介绍大把方法。这里采用最方便最有效的一种——链地址法,当有冲突发生时将具同一关键码的数据组成一个链表。下图展示了链地址法的使用:
二.简化版的hash_table
按照上面的分析和图示,并参考《编程珠玑》第15章中哈希表的实现,不难写出一个简单的哈希表,我们称之为简化版hash_table。该哈希表由一个指针数组组成,数组中每个元素都是链表的表头指针,程序分为hash_table.h,hash_table.cpp和main.cpp。
1.hash_table.h
- #pragmaonce
- #defineNULL0
- //简化版hash_table
- //byMoreWindows(http://blog.csdn.net/MoreWindows)
- structNode
- {
- intval;
- Node*next;
- Node(intn)
- this->val=n;
- this->next=NULL;
- }
- };
- classhash_table
- public:
- hash_table(constintntablesize);
- ~hash_table();
- boolinsert(intn);
- voidinsert(int*pFirst,int*pLast);
- boolfind(intsize();
- intHashFun(intm_nTableSize;
- intm_nTableDataCount;
- Node**m_ppTable;
- };
2.hash_table.cpp
- #include"hash_table.h"
- #include<malloc.h>
- #include<memory.h>
- hash_table::hash_table(intntablesize)
- {
- m_nTableSize=ntablesize;
- m_ppTable=(Node**)malloc(sizeof(Node*)*m_nTableSize);
- if(m_ppTable==NULL)
- return;
- m_nTableDataCount=0;
- memset(m_ppTable, }
- hash_table::~hash_table()
- free(m_ppTable);
- m_ppTable=NULL;
- m_nTableDataCount=0;
- m_nTableSize=0;
- intinlinehash_table::HashFun(intn)
- return(n^0xdeadbeef)%m_nTableSize;
- inthash_table::size()
- returnm_nTableDataCount;
- boolhash_table::insert(intkey=HashFun(n);
- //在该链表中查找该数是否已经存在
- for(Node*p=m_ppTable[key];p!=NULL;p=p->next)
- if(p->val==n)
- returntrue;
- //在链表的头部插入
- Node*pNode=newNode(n);
- if(pNode==NULL)
- false;
- pNode->next=m_ppTable[key];
- m_ppTable[key]=pNode;
- m_nTableDataCount++;
- boolhash_table::find(for(Node*pNode=m_ppTable[key];pNode!=NULL;pNode=pNode->next)
- if(pNode->val==n)
- true;
- voidhash_table::insert(int*pLast)
- for(int*p=pFirst;p!=pLast;p++)
- this->insert(*p);
- }