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