HashTable.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "HashTable.h"
  2. void HashTableTest() {
  3. printf("\n=======HashTableTest()==========\n");
  4. char *names[] = { "John", "Mary", "George", "Mickey", "Snoopy", "Bob", "Jack" };
  5. char *ids[] = { "1", "2", "3", "4", "5", "6", "7" };
  6. HashTable* table = HashTableNew(3);
  7. int i;
  8. for (i=0; i<5; i++)
  9. HashTablePut(table, names[i], ids[i]);
  10. // for (i=0; i<7; i++)
  11. // printf("id=%s\n", HashTableGet(table, names[i]));
  12. // HashTableEach(table, strPrintln);
  13. HashTableFree(table);
  14. }
  15. int hash(char *key, int range) {
  16. int i, hashCode=0;
  17. for (i=0; i<strlen(key); i++) {
  18. BYTE value = (BYTE) key[i];
  19. hashCode += value;
  20. hashCode %= range;
  21. }
  22. return hashCode;
  23. }
  24. Entry* EntryNew(char *key, void *data) {
  25. Entry* e = ObjNew(Entry, 1);
  26. e->key = key;
  27. e->data = data;
  28. return e;
  29. }
  30. void EntryFree(Entry *e) {
  31. ObjFree(e);
  32. }
  33. int EntryCompare(Entry *e1, Entry *e2) {
  34. return strcmp(e1->key, e2->key);
  35. }
  36. HashTable* HashTableNew(int size) {
  37. Array *table = ArrayNew(size);
  38. int i;
  39. for (i=0; i<table->size; i++)
  40. ArrayAdd(table, ArrayNew(1));
  41. return table;
  42. }
  43. void HashTableFree(HashTable *table) {
  44. int ti, hi;
  45. for (ti=0; ti<table->size; ti++) {
  46. Array *hitArray = table->item[ti];
  47. ArrayFree(hitArray, (FuncPtr1) EntryFree);
  48. }
  49. ArrayFree(table, NULL);
  50. }
  51. Entry keyEntry;
  52. // 尋找雜湊表中 key 所對應的元素並傳回
  53. void *HashTableGet(HashTable *table, char *key) {
  54. int slot = hash(key, table->size); // 取得雜湊值 (列號)
  55. Array *hitArray = (Array*) table->item[slot]; // 取得該列
  56. // 找出該列中是否有包含 key 的配對
  57. keyEntry.key = key;
  58. int keyIdx = ArrayFind(hitArray, &keyEntry, EntryCompare);
  59. if (keyIdx >= 0) { // 若有,則傳回該配對的資料元素
  60. Entry *e = hitArray->item[keyIdx];
  61. return e->data;
  62. }
  63. return NULL; // 否則傳回 NULL
  64. }
  65. // 將 (key, data) 配對放入雜湊表中
  66. void HashTablePut(HashTable *table, char *key, void *data) {
  67. Entry *e;
  68. int slot = hash(key, table->size); // 取得雜湊值 (列號)
  69. Array *hitArray = (Array*) table->item[slot]; // 取得該列
  70. keyEntry.key = key;
  71. int keyIdx = ArrayFind(hitArray, &keyEntry, EntryCompare);
  72. if (keyIdx >= 0) { // 若有,則傳回該配對的資料元素
  73. e = hitArray->item[keyIdx];
  74. e->data = data;
  75. } else {
  76. e= EntryNew(key, data);// 建立配對
  77. ArrayAdd(hitArray, e); // 放入對應的列中
  78. }
  79. }
  80. void HashTableEach(HashTable *table, FuncPtr1 f) {
  81. int i, j;
  82. for (i=0; i<table->count; i++) {
  83. Array *hits = table->item[i];
  84. for (j=0; j<hits->count; j++) {
  85. Entry *e = hits->item[j];
  86. f(e->data);
  87. }
  88. }
  89. }
  90. Array* HashTableToArray(HashTable *table) {
  91. Array *array = ArrayNew(table->count);
  92. int i, j;
  93. for (i=0; i<table->count; i++) {
  94. Array *hits = table->item[i];
  95. for (j=0; j<hits->count; j++) {
  96. Entry *e = hits->item[j];
  97. ArrayAdd(array, e->data);
  98. }
  99. }
  100. return array;
  101. }