SOGO論壇
  登入   註冊   找回密碼
查看: 565|回覆: 0
列印 上一主題 下一主題

[技術文章] HashTable -- 雜湊表 [複製連結]

Rank: 11Rank: 11Rank: 11Rank: 11

熱心參予論壇活動及用心回覆主題勳章 數位硬體勳章

狀態︰ 離線
跳轉到指定樓層
1
發表於 2012-7-11 00:21:17 |只看該作者 |倒序瀏覽
檔案:HashTable.h

#ifndef HASHTABLE_H
#define HASHTABLE_H

#include "Array.h"

typedef struct {
  char *key;
  void *data;
} Entry;

Entry* EntryNew(char *key, void *data);
int EntryCompare(Entry *e1, Entry *e2);

int hash(char *key, int range);

#define HashTable Array

HashTable* HashTableNew(int size);
void HashTableFree(HashTable *table);
void HashTablePut(HashTable *table, char *key, void *data);
void *HashTableGet(HashTable *table, char *key);
void HashTableEach(HashTable *table, FuncPtr1 f);
Array* HashTableToArray(HashTable *table);
void HashTableTest();

#endif

檔案:HashTable.c

#include "HashTable.h"

void HashTableTest() {
  printf("\n=======HashTableTest()==========\n");
  char *names[] = { "John", "Mary", "George", "Mickey", "Snoopy", "Bob", "Jack" };
  char *ids[]    = { "1",    "2",    "3",      "4",      "5",      "6",   "7" };
  HashTable* table = HashTableNew(3);
  int i;
  for (i=0; i<5; i++)
    HashTablePut(table, names[i], ids[i]);
//  for (i=0; i<7; i++)
//    printf("id=%s\n", HashTableGet(table, names[i]));
//  HashTableEach(table, strPrintln);
  HashTableFree(table);
}

int hash(char *key, int range) {
  int i, hashCode=0;
  for (i=0; i<strlen(key); i++) {
    BYTE value = (BYTE) key[i];
    hashCode += value;
    hashCode %= range;
  }
  return hashCode;
}

Entry* EntryNew(char *key, void *data) {
  Entry* e = ObjNew(Entry, 1);
  e->key = key;
  e->data = data;
  return e;
}

void EntryFree(Entry *e) {
  ObjFree(e);
}

int EntryCompare(Entry *e1, Entry *e2) {
  return strcmp(e1->key, e2->key);
}

HashTable* HashTableNew(int size) {
  Array *table = ArrayNew(size);
  int i;
  for (i=0; i<table->size; i++)
    ArrayAdd(table, ArrayNew(1));
  return table;
}

void HashTableFree(HashTable *table) {
  int ti, hi;
  for (ti=0; ti<table->size; ti++) {
    Array *hitArray = table->item[ti];
    ArrayFree(hitArray, (FuncPtr1) EntryFree);
  }
  ArrayFree(table, NULL);
}

Entry keyEntry;
// 尋找雜湊表中 key 所對應的元素並傳回
void *HashTableGet(HashTable *table, char *key) {
  int slot = hash(key, table->size);            // 取得雜湊值 (列號)
  Array *hitArray = (Array*) table->item[slot]; // 取得該列
  // 找出該列中是否有包含 key 的配對
  keyEntry.key = key;
  int keyIdx = ArrayFind(hitArray, &keyEntry, EntryCompare);
  if (keyIdx >= 0) { // 若有,則傳回該配對的資料元素
    Entry *e = hitArray->item[keyIdx];
    return e->data;
  }
  return NULL; // 否則傳回 NULL
}

// 將 (key, data) 配對放入雜湊表中
void HashTablePut(HashTable *table, char *key, void *data) {
  Entry *e;
  int slot = hash(key, table->size);            // 取得雜湊值 (列號)
  Array *hitArray = (Array*) table->item[slot]; // 取得該列
  keyEntry.key = key;
  int keyIdx = ArrayFind(hitArray, &keyEntry, EntryCompare);
  if (keyIdx >= 0) { // 若有,則傳回該配對的資料元素
    e = hitArray->item[keyIdx];
    e->data = data;
  } else {
    e= EntryNew(key, data);// 建立配對
    ArrayAdd(hitArray, e); // 放入對應的列中
  }
}

void HashTableEach(HashTable *table, FuncPtr1 f) {
  int i, j;
  for (i=0; i<table->count; i++) {
    Array *hits = table->item[i];
    for (j=0; j<hits->count; j++) {
      Entry *e = hits->item[j];
      f(e->data);
    }
  }
}

Array* HashTableToArray(HashTable *table) {
  Array *array = ArrayNew(table->count);
  int i, j;
  for (i=0; i<table->count; i++) {
    Array *hits = table->item[i];
    for (j=0; j<hits->count; j++) {
      Entry *e = hits->item[j];
      ArrayAdd(array, e->data);
    }
  }
  return array;
喜歡嗎?分享這篇文章給親朋好友︰
               感謝作者     

請注意︰利用多帳號發表自問自答的業配文置入性行銷廣告者,將直接禁訪或刪除帳號及全部文章!
您需要登錄後才可以回覆 登入 | 註冊


本論壇為非營利自由討論平台,所有個人言論不代表本站立場。文章內容如有涉及侵權,請通知管理人員,將立即刪除相關文章資料。侵權申訴或移除要求:abuse@oursogo.com

GMT+8, 2025-2-11 17:16

© 2004-2025 SOGO論壇 OURSOGO.COM
回頂部