哈希表(Hash)—— 查找算法 (基于链地址法)

目录

一、链地址法

二、算法

三、相关定义


一、链地址法

基本思想:将所有哈希地址为 i 的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第 i 个单元中,因而查找、插入和删除主要在同义词链中进行。

哈希表(Hash)—— 查找算法 (基于链地址法)_第1张图片

 


二、算法

HASH_RESULT hash_add_int(HashTable *table, const char *key, int value ) {
    HashEntry *p;

	int h = hash_string(key) % table->size;

    if (table->bucket[h] == NULL) { /* 键值key映射得到的哈希地址h不在哈希表中 */
        p = (HashEntry *)malloc(sizeof(HashEntry));
        if (p == NULL) return HASH_ERROR;

        /* 生成新的键值对 */
        p->key.str_value = (char *)malloc(strlen(key));
		if (p->key.str_value == NULL) {
			free(p);
			return HASH_ERROR;
		}
		strcpy(p->key.str_value, key);
		p->value.int_value = value; 
		p->next = NULL;

		table->bucket[h] = p; /* 新键值对成为新同义词链的第一个结点 */
		
		return HASH_ADDED;
    }

    p = table->bucket[h]; /* p为头指针 */
    /* 遍历哈希地址为h的元素构成的同义词链 */
    while (p != NULL) {
        if (strcmp(p->key.str_value, key) == 0) { /* 键值key相同 */
            if (p->value.int_value == value) { /* value值也相同 */
                return HASH_ALREADY_ADDED;
            } else { /* value值不同,更新value值 */
                p->value.int_value = value;
                return HASH_REPLACED_VALUE;
            }
        } else {
            if (p->next != NULL)
                p = p->next;
            else
                break;
        }
    }
    
    /* 与其它键值对的键值key均不同,则生成新键值对,并将其链入同义词链 */
    HashEntry *q;
	q = (HashEntry *)malloc(sizeof(HashEntry));
	if (q == NULL) return HASH_ERROR;
	
	q->key.str_value = (char *)malloc(strlen(key));
	if (q->key.str_value == NULL) {
		free(q);
		return HASH_ERROR;
	}
    strcpy(q->key.str_value, key);
	q->value.int_value = value;
    q->next = NULL;

	p->next = q;
	
	return HASH_ADDED;
}

三、相关定义

typedef enum {
    HASH_OK,
    HASH_ERROR,
    HASH_ADDED,
    HASH_REPLACED_VALUE,
    HASH_ALREADY_ADDED,
    HASH_DELETED,
    HASH_NOT_FOUND,
} HASH_RESULT; /* 相关函数的返回类型 */

typedef struct __HashEntry HashEntry;
struct __HashEntry {
    union{
        char  *str_value;
        double dbl_value;
        int    int_value;
    } key; /* 可供选择的键值key类型 */
    union {
        char  *str_value;
        double dbl_value;
        int    int_value;
        long   long_value;
        void  *ptr_value;
    } value; /* 可供选择的value值类型 */
    HashEntry *next; /* 指向下一个同义键值对 */
}; /* 键值对的类型 */

struct __HashTable {
    HashEntry **bucket; /* 指向头指针数组 */
    int size;
    HASH_RESULT last_error;
}; /* 哈希表的类型 */
typedef struct __HashTable HashTable;

哈希表相关说明:

  • HASH_RESULT 类型为相关函数的返回类型;
  • HashEntry 为哈希表所保存元素(即键值对)类型;
  • HashTable 为哈希表,其中 bucket 指向大小为size、元素类型为 HashEntry * 的指针数组;
  • 哈希表采用链地址法处理冲突。

你可能感兴趣的:(散列表,哈希算法,数据结构)