Hash表的实现

1 #pragma once
2
3 #include<cstdlib>
4 #include<cmath>
5 #include<cassert>
6 #include<iostream>
7
8 template<typename valueType>
9  class HashTable
10 {
11 //节点状态
12 enum KindOfNode
13 {
14 Active, //活跃
15 Empty, //
16 Deleted //已删除
17 };
18 public:
19 //查找_key是否在表中,若在,返回0;否则返回-1;找到时,m,n为节点的位置
20 int find(unsigned long _key);
21
22 //插入节点,若该节点已在表中,返回1;若插入成功,返回0,表满,返回-1
23 int insert(unsigned long _key,const valueType &_value);
24
25 //删除节点 若节点不存在,返回-1,成功时返回0
26 int remove(unsigned long _key);
27 public:
28 //返回Hash表空间利用率
29 double getFullRate()const;
30
31 //表是否为满
32 bool isFull() const
33 {
34 return currentSize == maxSize + maxList;
35 }
36
37 //清除表内容
38 void clear();
39
40 //default 5,the better one
41 void setList(int len = 5)
42 {
43 if(listLen == -1)
44 {
45 listLen=len;
46 }
47 }
48
49 double getOverflowRate()const
50 {
51 return double(maxList)/currentSize;
52 }
53
54 public:
55 //构造函数line default 5,a better range
56 HashTable(unsigned long maxline,unsigned short line=5);
57
58 ~HashTable();
59
60 private:
61 //哈希节点
62 struct HashNode
63 {
64 unsigned long key; //name
65 valueType value; //value
66 KindOfNode state; //节点状态
67 HashNode():state(Empty){}
68 ~HashNode(){}
69 };
70
71 //链表节点 存储溢出数据
72 struct list_node
73 {
74 unsigned long key;
75 valueType value;
76 list_node *next;
77 list_node():next(NULL){}
78 };
79
80 unsigned long currentSize; //当前数据量
81 unsigned long maxSize; //最大数据量
82 unsigned long maxLine; //每行最大值
83 unsigned short lines; //行数
84 HashNode **ht; //哈希阵列
85 unsigned long *modTable; //每行的模数
86 unsigned long m,n; //查找时存储节点位置,否则做为临时变量使用
87 HashNode *mem; //哈希表的实际存储空间
88 list_node **Overflow_list; //溢出链
89 unsigned long maxList; //list current size
90 int listLen; //list length default -1---no limit
91
92 private:
93 void getMode(); //生成模数
94 void clear_Overflow(); //清除溢出链数据
95 };

cpp文件
1 #include "StdAfx.h"
2 #include "HashTab.h"
3
4 template<typename valueType>
5 HashTable<valueType>::HashTable(unsigned long maxline,unsigned short line)
6 {
7 maxLine = maxline;
8 lines = line;
9 currentSize = 0;
10 ht = new HashNode *[lines];
11 assert(ht!=NULL);
12
13 mem = new HashNode[maxLine*lines]; //实际空间
14 assert(mem != NULL);
15 int i;
16 for(i=0;i<lines;i++) //分配空间到哈希阵列
17 ht[i]=mem+maxLine*i;
18
19 modTable=new unsigned long[lines+1];//modTable[lines] Overlist
20 assert(modTable!=NULL);
21 getMode();
22 /*-----------not must need--------------------------------*/
23 long temp=modTable[0];
24 for(i=0;i<lines+1;i++)
25 modTable[i]=modTable[i+1];
26 modTable[lines]=temp;
27 /*------------------------------------------------------*/
28 maxSize=0;
29 for(i=0;i<lines;i++)
30 maxSize += modTable[i];//最大值
31
32 Overflow_list = new list_node *[ modTable[lines] ];//Overflow head list ,all NULL pointer
33 assert(Overflow_list!=NULL);
34 listLen = -1;
35 maxList = 0;
36 }
37
38
39 template<typename valueType>
40 void HashTable<valueType>::getMode()
41 { //采用 6n+1 6n-1 素数集中原理
42 if(maxLine<5){this->~HashTable();exit(-1);}
43
44 unsigned long t,m,n,p;
45 int i,j,a,b,k;
46 int z=0;
47
48 for(t=maxLine/6;t>=0,z<=lines;t--)
49 {
50 i=1;j=1; k=t%10;
51 m=6*t; /**i,j的值 是是否进行验证的标志也是对应的6t-1和6t+1的素性标志**/
52 if(((k-4)==0)||((k-9)==0)||((m+1)%3==0))j=0;/*此处是简单验证6*t-1,6*t+1 是不是素数,借以提高素数纯度**/
53 if(((k-6)==0)||((m-1)%3==0))i=0; /***先通过初步判断去除末尾是5,及被3整除的数***/
54 for(p=1;p*6<=sqrt(m+1)+2;p++ )
55 {
56 n=p*6; /**将6*p-1和6*p+1看作伪素数来试除*****/
57 k=p%10;
58 a=1;b=1; /**同样此处a,b的值也是用来判断除数是否为素数提高除数的素数纯度**/
59 if(((k-4)==0)||((k-9)==0))a=0;
60 if(((k-6)==0))b=0;
61 if(i){ /*如果i非零就对m-1即所谓6*t-1进行验证,当然还要看除数n+1,n-1,素性纯度*/
62 if(a){if((m-1)%(n+1)==0)i=0;} /***一旦被整除就说明不是素数故素性为零即将i 赋值为零***/
63 if(b){if((m-1)%(n-1)==0)i=0;}
64 }
65 if(j){ /**如果j非零就对m+1即所谓6*t+1进行验证,当然还要看除数n+1,n-1,素性纯度*/
66 if(a){if((m+1)%(n+1)==0)j=0;} /***一旦被整除就说明不是素数故素性为零即将j 赋值为零***/
67 if(b){if((m+1)%(n-1)==0)j=0;}
68 }
69 if((i+j)==0)break; /**如果已经知道6*t-1,6*t+1都不是素数了那就结束试除循环***/
70 }
71 if(j){modTable[z++]=m+1;if(z> lines)return;}
72 if(i){modTable[z++]=m-1;if(z> lines)return;}
73 }
74 }
75
76 template<typename valueType>
77 HashTable<valueType>::~HashTable()
78 {
79 delete []mem; //释放空间
80 delete []ht;
81 delete []modTable;
82
83 clear_Overflow();
84 delete []Overflow_list;
85 }
86
87 template<typename valueType>
88 int HashTable<valueType>::find(unsigned long _key)
89 {
90 int i;
91 for(i=0;i<lines;i++){
92 m=i;n=(_key+maxLine)%modTable[m];
93 if(ht[m][n].key==_key&&ht[m][n].state==Active)
94 return 0;
95 }
96 if(listLen==0)return -1;
97 m=lines;n=(_key+maxLine)%modTable[m];
98 list_node *pre=Overflow_list[n];
99 while(pre!=NULL){
100 if(pre->key==_key)return 0;
101 pre=pre->next;
102 }
103 return -1;
104 }
105
106 template<typename valueType>
107 int HashTable<valueType>::insert(unsigned long _key,const valueType &_value)
108 {
109 if(find(_key)==0)return 1; //已存在
110
111 int i,len=0;
112 for(i=0;i<lines;i++){
113 m=i;n=(_key+maxLine)%modTable[m];
114 if(ht[m][n].state!=Active){ //阵列中找到空位,插入数据
115 ht[m][n].key=_key;
116 ht[m][n].value=_value;
117 ht[m][n].state=Active;
118 currentSize++;
119 return 0;
120 }
121 }
122 if(listLen==0)return -1;
123
124 //阵列已满,插入溢出链表
125 m=lines;n=(_key+maxLine)%modTable[m];
126 list_node *pre=Overflow_list[n];
127
128 list_node *now=new list_node;
129 now->key=_key;
130 now->value=_value;
131
132 if(pre==NULL){
133 Overflow_list[n]=now;
134 }
135 else{
136 len=1;
137 while(pre->next!=NULL){pre=pre->next;len++;}
138 if(listLen>0&&len>=listLen)return -1; // full ;if listLen<0 no limit ,continue the left operation
139 pre->next=now;
140 }
141 currentSize++;
142 maxList++;
143
144 return 0;
145 }
146
147
148 template<typename valueType>
149 int HashTable<valueType>::remove(unsigned long _key)
150 {
151 if(find(_key)!=0)return -1;
152 if(m<lines){ //节点在阵列中
153 ht[m][n].state=Deleted; //节点状态置为Deleted
154 currentSize--;
155 }
156 else{ //节点在溢出链中
157 list_node *pre=Overflow_list[n],*now;
158 if(pre->key==_key){
159 Overflow_list[n]=pre->next;
160 delete pre;
161 }
162 else{
163 while(pre->next->key!=_key&&pre->next!=NULL)
164 pre=pre->next;
165 now=pre->next;
166 pre->next=now->next;
167 delete now;
168 }
169 currentSize--;maxList--;
170 }
171 return 0;
172 }
173
174 template<typename valueType>
175 double HashTable<valueType>::getFullRate()const
176 {
177 return double(currentSize)/(maxSize+maxList); //空间使用率
178 }
179
180 template<typename valueType>
181 void HashTable<valueType>::clear()
182 {
183 int i,j;
184 for(i=0;i<lines;i++) //把所有节点状态置为Empty
185 for(j=0;j<modTable[i];j++)
186 ht[i][j].state=Empty;
187 if(listLen!=0)clear_Overflow();
188 maxList=0;
189 currentSize=0;
190 }
191
192 template<typename valueType>
193 void HashTable<valueType>::clear_Overflow()
194 {
195 list_node *pre=NULL,*now=NULL;
196 for(int i=0;i<modTable[lines];i++)
197 {
198 pre=Overflow_list[i];
199 if(pre==NULL)continue;
200 while(pre->next!=NULL){
201 now=pre->next;
202 pre->next=now->next;
203 delete now;
204 }
205 delete pre;
206 Overflow_list[i]=NULL;
207 }
208 }

posted @ 2011-03-30 17:52  狼哥2  阅读(825)  评论(0编辑  收藏  举报