C實現HashTable

1.HashTable

        散列表:可根據關鍵字直接訪問的數據結構。關鍵字與存儲地址存在映射關係。(以存儲空間換查找時間,空間換時間數據結構)

2.關鍵字與存儲地址的映射關係

       通過散列函數將關鍵字映射指定地址。

       設計散列函數:

       1.直接定址:hash(key) = a*key+b    2.除留餘數法:hash(key) = key%p(簡單常用)

       3.數字分析法 4.平方取中法 5.摺疊法

3.散列地址衝突

      不同key映射相同散列會造成地址衝突,解決地址衝突的兩種方法:

      1.開放地址:將地址衝突的key存儲到空閒的散列表中(Haddress=(hash(key)+d)%p,p爲表長)

      d爲造成地址衝突後下一地址地增量

      (1)d隨衝突次數增加而增加,稱線性探測法

      (2)d隨隨衝突次數以平方增長,稱平方探測法

      (3)d取對key再散列hash2*衝突次數,稱再散列法或雙散列法

      (4)d取僞隨機序列(指有某種隨機特性的序列,序列元素間有確定關係存在),稱僞隨機序列法

      2.鏈接法:

       用鏈表存儲同地址衝突關鍵字,每一散列地址對應一鏈表。(有利於多元素的插入和刪除情況)

4.C實現(散列函數採取除留餘數法,地址衝突採取鏈接法解決)

#include <stdio.h>
#include <malloc.h>
#define OK 1
#define ERROR -1
#define CAPACITY 10 
#define ElemType int
#define Status int

typedef struct _Node {
	ElemType value;
	_Node* next;
}Node;
typedef struct _HashTable {
	Node elems[CAPACITY];
	int count;
	int capacity;
}HashTable;

Status InitHashTable(HashTable* ht);
Status InsertNode(HashTable* ht, ElemType elem);
Status Search(HashTable* ht, ElemType elem);
Node* new_Node();
int hash(int key); //計算key 對應地址, 求餘取址
Status addLinkNode(Node* list, ElemType elem);

void print_table(HashTable* ht) {
	Node* head;
	for (int i = 0; i < CAPACITY; i++) {
		head = &ht->elems[i];
		printf("elem[%d].head->:", i);
		while (head->next) {
			head = head->next;
			printf(" %d ->", head->value);
		}
		printf("\n");
	}
}

int main() {
	int key[18] = { 1,2,4,55,11,44,22,33,77,4,5,10,8,9,666,12,14,15};
	HashTable ht;
	InitHashTable(&ht);
	for (int i = 0; i < 18; i++) InsertNode(&ht, key[i]);
	print_table(&ht);
	int n; scanf("%d", &n);
	return 0;
}
Status InitHashTable(HashTable* ht) {
	for (int i = 0; i < CAPACITY; i++) {
		ht->elems[i] = *new_Node();
		ht->elems[i].value = -1;
		ht->elems[i].next = NULL;
	}
	ht->capacity = CAPACITY;
	return OK;
}
int hash(int key) {
	return key % CAPACITY;
}
Status InsertNode(HashTable* ht, ElemType elem) {
	int hash_address = hash(elem);
	int status = addLinkNode(&ht->elems[hash_address],elem); //指定hashaddress的單鏈表添加元素
	if (status == OK) {
		ht->count++;
		return OK;
	}
	return ERROR;
}
Status Search(HashTable* ht, ElemType elem) {
	return 0;
}
Node* new_Node() {
	return (Node*)malloc(sizeof(Node));
}
Status addLinkNode(Node* list, ElemType elem) {
	Node* head = list;
	while (head->next) {
		head = head->next;
	}
	Node* newnode = new_Node();
	newnode->value = elem;
	newnode->next = NULL;
	head->next = newnode;
	return OK;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章