1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdbool.h>
4
5 typedef int ElementType;
6 enum KindOfEntry {Legitimate,Empty,Deleted};
7
8 struct OAHashListNode
9 {
10 ElementType Element;
11 int ExistNum;
12 enum KindOfEntry State;
13 };
14
15 struct OAHashTable
16 {
17 int TableSize;
18 int CurrentSize;
19 struct OAHashListNode *OAHashNodeList;
20 };
21
22 bool _isPrime(int Input)
23 {
24 if (Input == 2 || Input == 3)
25 {
26 return true;
27 }
28 if (Input % 6 != 1 && Input % 6 != 5)
29 {
30 return false;
31 }
32 int i;
33 for (i = 5; i*i <= Input; i += 6)
34 {
35 if (Input % i == 0 || Input % (i+2) == 0)
36 {
37 return false;
38 }
39 }
40 return true;
41 }
42
43 int NextPrime(int Input)
44 {
45 bool state = _isPrime(Input);
46 while(!state)
47 {
48 state = _isPrime(++Input);
49 }
50 return Input;
51 }
52
53 int Hash(ElementType Key,int TSize)
54 {
55 return Key % TSize;
56 }
57
58 struct OAHashTable* OAHashTableInit(int TableSizeInput)
59 {
60 struct OAHashTable *HashTable;
61 int i;
62
63 HashTable = malloc(sizeof(struct OAHashTable));
64 HashTable -> TableSize = NextPrime(TableSizeInput);
65 HashTable -> CurrentSize = 0;
66 HashTable -> OAHashNodeList = malloc(HashTable->TableSize*sizeof(struct OAHashListNode));
67
68 for(i = 0; i < HashTable -> TableSize; i ++)
69 {
70 HashTable -> OAHashNodeList[i].State = Empty;
71 HashTable -> OAHashNodeList[i].ExistNum = 0;
72 }
73 return HashTable;
74 }
75
76 void OAHashTableDelete(struct OAHashTable* HashTable)
77 {
78 free(HashTable->OAHashNodeList);
79 }
80
81 //if doesn't find,return a index that HashTable->OAHashNodeList[Index].State == Empty
82 int OAHashListNodeFind(struct OAHashTable* HashTable,ElementType ToBeFind)
83 {
84 int Index;
85 int TmpAssist = 0;
86
87 Index = Hash(ToBeFind,HashTable->TableSize);
88 //F(i) = F(i-1) + 2i - 1
89 while(HashTable->OAHashNodeList[Index].State != Empty
90 && HashTable->OAHashNodeList[Index].Element != ToBeFind)
91 {
92 Index += 2 * ++TmpAssist - 1;
93 if(Index >= HashTable->TableSize)
94 Index -= HashTable->TableSize;
95 }
96 return Index;
97 }
98
99 struct OAHashTable* OAHashListRehash(struct OAHashTable* HashTable)
100 {
101 int i,OldSize,OldCurrent;
102 struct OAHashListNode* OldNodes;
103 struct OAHashTable* NewHashTable;
104
105 OldNodes = HashTable->OAHashNodeList;
106 OldSize = HashTable->TableSize;
107 OldCurrent = HashTable->CurrentSize;
108
109 NewHashTable = OAHashTableInit(2*OldSize);
110 NewHashTable->CurrentSize = OldCurrent;
111 for(i = 0;i < OldSize;i ++)
112 {
113 if(OldNodes[i].State == Legitimate)
114 {
115 int Index = OAHashListNodeFind(NewHashTable,OldNodes[i].Element);
116 // printf("%d\n",Index);
117 NewHashTable->OAHashNodeList[Index].Element = OldNodes[i].Element;
118 NewHashTable->OAHashNodeList[Index].ExistNum = OldNodes[i].ExistNum;
119 NewHashTable->OAHashNodeList[Index].State = OldNodes[i].State;
120 }
121 }
122 OAHashTableDelete(HashTable);
123 return NewHashTable;
124 }
125
126 struct OAHashTable* OAHashListNodeInsert(struct OAHashTable* HashTable,ElementType ToBeInsert)
127 {
128 int Index;
129
130 Index = OAHashListNodeFind(HashTable,ToBeInsert);
131
132 HashTable->OAHashNodeList[Index].State = Legitimate;
133 HashTable->OAHashNodeList[Index].Element = ToBeInsert;
134 HashTable->OAHashNodeList[Index].ExistNum ++;
135 HashTable->CurrentSize ++;
136
137 if(2*HashTable->CurrentSize >= HashTable->TableSize)
138 {
139 struct OAHashTable* NewHashTable = OAHashListRehash(HashTable);
140 HashTable = NewHashTable;
141 return NewHashTable;
142 }
143 return HashTable;
144 }
145
146 //return the ExistNum,if not find return -1,if error return -2
147 int OAHashListNodeDelete(struct OAHashTable* HashTable,ElementType ToBeDelete)
148 {
149 int Index;
150
151 Index = OAHashListNodeFind(HashTable,ToBeDelete);
152 if(HashTable->OAHashNodeList[Index].State == Empty)
153 {
154 return -1;
155 }
156 else
157 {
158 HashTable->OAHashNodeList[Index].State = Deleted;
159 HashTable->OAHashNodeList[Index].ExistNum --;
160 return HashTable->OAHashNodeList[Index].ExistNum;
161 }
162
163 return -2;
164 }
165
166 int main()
167 {
168 struct OAHashTable* HashTable = OAHashTableInit(5);
169
170 HashTable = OAHashListNodeInsert(HashTable,23);
171 HashTable = OAHashListNodeInsert(HashTable,23);
172 HashTable = OAHashListNodeInsert(HashTable,23);
173 OAHashListNodeDelete(HashTable,23);
174 HashTable = OAHashListNodeInsert(HashTable,47);
175 HashTable = OAHashListNodeInsert(HashTable,50);
176
177 int OutputIndex = OAHashListNodeFind(HashTable,23);
178 printf("%d %d\n",HashTable->OAHashNodeList[OutputIndex].Element,HashTable->OAHashNodeList[OutputIndex].ExistNum);
179 OutputIndex = OAHashListNodeFind(HashTable,47);
180 printf("%d %d\n",HashTable->OAHashNodeList[OutputIndex].Element,HashTable->OAHashNodeList[OutputIndex].ExistNum);
181 OutputIndex = OAHashListNodeFind(HashTable,39);
182
183 if(HashTable->OAHashNodeList[OutputIndex].State == Empty)
184 printf("where is my princess Hatsune Miku?\n");
185 OAHashTableDelete(HashTable);
186 return 0;
187 }