【数据结构】哈希表

处理整型

头文件

#ifndef  __HASHTABLE_H__
#define  __HASHTABLE_H__



#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include <string.h>

static size_t GetNextPrime(size_t value)
{
	int i = 0;
	//const int _PrimeSize = 28;
	static const unsigned long _PrimeList[28] =
	{
		53ul, 97ul, 193ul, 389ul, 769ul,
		1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
		49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
		1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
		50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
		1610612741ul, 3221225473ul, 4294967291ul
	};

	for (; i < 28; ++i)
	{
		if (_PrimeList[i] > value)
		{
			return _PrimeList[i];
		}
	}

	return _PrimeList[27];
}

static size_t StrHash(const char* str)
{
	size_t hash = 0;
	size_t seed = 131;
	while (*str)
	{
		//hash += *str;
		hash = hash*seed + *str;
		++str;
	}

	/*printf("%u\n", hash);*/

	return hash;
}


typedef  int HTKeyType;
typedef int HTValueType;

enum State
{
	EMPTY,
	EXITS,
	DELETE,
};

typedef struct HashNode
{
	enum State		_state;
	HTKeyType	_key;
	HTValueType _value;
}HashNode;

typedef struct HashTable
{
	HashNode* tables;
	size_t len;   // 长度
	size_t size;  // 有效数据个数
}HashTable;

void HTInit(HashTable* ht, size_t len);
void HTDestory(HashTable* ht);
int HTInsert(HashTable* ht, HTKeyType key, HTValueType value);
int HTRemove(HashTable* ht, HTKeyType key);
HashNode* HTFind(HashTable* ht, HTKeyType key);
int HTSize(HashTable* ht);
int HTEmpty(HashTable* ht);
void HashPrint(HashTable* ht);



#endif

函数部分

#include "HashTable.h"

//闭散列

void HTInit(HashTable* ht, size_t len)
{
	size_t i;
	assert(len > 0);
	assert(ht);

	len = GetNextPrime(len);
	ht->len = len;
	ht->size = 0;
	ht->tables = (HashNode*)malloc(sizeof(HashNode)*ht->len);
	memset(ht->tables, 0, sizeof(HashNode)*len);
	for (i = 0; i < ht->len; i++)
	{
		ht->tables[i]._state = EMPTY;
	}
}

void HTDestory(HashTable* ht)
{
	assert(ht);
	free(ht->tables);
	ht->tables = NULL;
	ht->len = 0;
	ht->size = 0;
}

size_t HashTableFunc(HTKeyType key, size_t len)
{
	return  (key) % len;
}

void ExpendCapacity(HashTable *ht)//给数组增容变为新数组
{
	if ((ht->size * 10) / (ht->len) > 7)//如果当前的元素个数>数组长度的0.7增容减少哈希冲突
	{
		HashTable newht;
		HTInit(&newht, GetNextPrime(ht->len));
		for (unsigned int i = 0; i <ht->len; i++)
		{
			if (ht->tables[i]._state == EXITS)
			{
				HTInsert(&newht, ht->tables[i]._key, ht->tables[i]._value);
			}
		}
		HTDestory(ht);
		ht->len = newht.len;
		ht->size = newht.size;
		ht->tables = newht.tables;
	}
}

int HTInsert(HashTable* ht, HTKeyType key, HTValueType value)
{
	// 增容
	int i = 0;
	size_t index;
	size_t start;
	ExpendCapacity(ht);

	start = HashTableFunc(key, ht->len);
	index = start;
	while (ht->tables[index]._state == EXITS)
	{
		if (ht->tables[index]._key == key)
		{
			return 0;
		}
		else
		{
			/*++index;
			if (index == ht->_len){
			index = 0;
			}*/

			++i;
			index = start + i*i;
			index %= ht->len;
		}
	}
	ht->tables[index]._state = EXITS;
	ht->tables[index]._key = key;
	ht->tables[index]._value = value;
	ht->size++;
	return 1;
}
int HTRemove(HashTable* ht, HTKeyType key)
{
	assert(ht);
	HashNode* cur = HTFind(ht, key);//先查找位置
	if (cur == NULL)
	{
		return 0;
	}
	else
	{
		cur->_state = DELETE;//直接把状态置为删除
		ht->size--;
		return 1;
	}

}

HashNode* HTFind(HashTable* ht, HTKeyType key)
{
	assert(ht);
	int index = HashTableFunc(key, ht->len);
	int i = 1;
	while (ht->tables[index]._state != EMPTY)
	{
		if (ht->tables[index]._key == key)
		{
			if (ht->tables[index]._state == EXITS)
			{
				return &(ht->tables[index]);
			}
			else
			{
				return NULL;
			}
		}
		else
		{
			++index;
			if (index == ht->len)
			{
				index = 0;
			}
		}
	}
	return NULL;
}
int HTSize(HashTable* ht)
{
	assert(ht);
	return ht->size;
}
int HTEmpty(HashTable* ht)
{
	assert(ht);
	return ht->size == 0 ? 0 : 1;
}


void HashPrint(HashTable *ht)//打印数组
{
	unsigned int i = 0;
	for (i = 0; i < ht->len; i++)
	{
		if (ht->tables[i]._state == EXITS)
			printf("[%d]->Exits->%d\n", i, ht->tables[i]._key);
		else  if (ht->tables[i]._state == EMPTY)
		{
			printf("[%d]->Empty\n", i);
		}
		else
		{
			printf("[%d]->Delte\n", i);
		}
	}
	printf("\n");
}


测试

#include "HashTable.h"

void HTtest1()
{
	HashNode* ret;
	HashTable ht;
	size_t i;
	HTInit(&ht, 10);
	HTInsert(&ht, 7, 0);
	HTInsert(&ht, 17, 0);
	HTInsert(&ht, 27, 0);
	HTInsert(&ht, 8, 0);
	HashPrint(&ht);

	HTRemove(&ht, 17);
	ret = HTFind(&ht, 27);
	ret->_value = 10;
	HashPrint(&ht);
	/*for (i = 0; i < 10; ++i)
	{
		HTInsert(&ht, rand(), i);
	}
	HashPrint(&ht);*/
}








int  main()
{
	HTtest1();
	system("pause");
	return 0;
}

处理字符类型
头文件

#ifndef  __HASHTABLE_H__
#define  __HASHTABLE_H__



#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include <string.h>

static size_t GetNextPrime(size_t value)
{
	int i = 0;
	//const int _PrimeSize = 28;
	static const unsigned long _PrimeList[28] =
	{
		53ul, 97ul, 193ul, 389ul, 769ul,
		1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
		49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
		1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
		50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
		1610612741ul, 3221225473ul, 4294967291ul
	};

	for (; i < 28; ++i)
	{
		if (_PrimeList[i] > value)
		{
			return _PrimeList[i];
		}
	}

	return _PrimeList[27];
}

static size_t StrHash(const char* str)
{
	size_t hash = 0;
	size_t seed = 131;
	while (*str)
	{
		//hash += *str;
		hash = hash*seed + *str;
		++str;
	}

	/*printf("%u\n", hash);*/

	return hash;
}


typedef  char* HTKeyType;
typedef int HTValueType;

enum State
{
	EMPTY,
	EXITS,
	DELETE,
};

typedef struct HashNode
{
	enum State		_state;
	HTKeyType	_key;
	HTValueType _value;
}HashNode;

typedef struct HashTable
{
	HashNode* tables;
	size_t len;   // 长度
	size_t size;  // 有效数据个数
}HashTable;

void HTInit(HashTable* ht, size_t len);
void HTDestory(HashTable* ht);
int HTInsert(HashTable* ht, HTKeyType key, HTValueType value);
int HTRemove(HashTable* ht, HTKeyType key);
HashNode* HTFind(HashTable* ht, HTKeyType key);
int HTSize(HashTable* ht);
int HTEmpty(HashTable* ht);
void HashPrint(HashTable* ht);



#endif

函数

#include "HashTable.h"

//闭散列

void HTInit(HashTable* ht, size_t len)
{
	size_t i;
	assert(len > 0);
	assert(ht);

	len = GetNextPrime(len);
	ht->len = len;
	ht->size = 0;
	ht->tables = (HashNode*)malloc(sizeof(HashNode)*ht->len);
	memset(ht->tables, 0, sizeof(HashNode)*len);
	for (i = 0; i < ht->len; i++)
	{
		ht->tables[i]._state = EMPTY;
	}
}

void HTDestory(HashTable* ht)
{
	assert(ht);
	free(ht->tables);
	ht->tables = NULL;
	ht->len = 0;
	ht->size = 0;
}

size_t HashTableFunc(HTKeyType key, size_t len)
{
	return  StrHash(key) % len;
}

void ExpendCapacity(HashTable *ht)//给数组增容变为新数组
{
	if ((ht->size * 10) / (ht->len) > 7)//如果当前的元素个数>数组长度的0.7增容减少哈希冲突
	{
		HashTable newht;
		HTInit(&newht, GetNextPrime(ht->len));
		for (unsigned int i = 0; i <ht->len; i++)
		{
			if (ht->tables[i]._state == EXITS)
			{
				HTInsert(&newht, ht->tables[i]._key, ht->tables[i]._value);
			}
		}
		HTDestory(ht);
		ht->len = newht.len;
		ht->size = newht.size;
		ht->tables = newht.tables;
	}
}

int HTInsert(HashTable* ht, HTKeyType key, HTValueType value)
{
	// 增容
	int i = 0;
	size_t index;
	size_t start;
	ExpendCapacity(ht);

	start = HashTableFunc(key, ht->len);
	index = start;
	while (ht->tables[index]._state == EXITS)
	{
		if (ht->tables[index]._key == key)
		{
			return 0;
		}
		else
		{
			/*++index;
			if (index == ht->_len){
			index = 0;
			}*/

			++i;
			index = start + i*i;
			index %= ht->len;
		}
	}
	ht->tables[index]._state = EXITS;
	ht->tables[index]._key = key;
	ht->tables[index]._value = value;
	ht->size++;
	return 1;
}
int HTRemove(HashTable* ht, HTKeyType key)
{
	assert(ht);
	HashNode* cur = HTFind(ht, key);//先查找位置
	if (cur == NULL)
	{
		return 0;
	}
	else
	{
		cur->_state = DELETE;//直接把状态置为删除
		ht->size--;
		return 1;
	}

}

HashNode* HTFind(HashTable* ht, HTKeyType key)
{
	assert(ht);
	int index = HashTableFunc(key, ht->len);
	int i = 1;
	while (ht->tables[index]._state != EMPTY)
	{
		if (ht->tables[index]._key == key)
		{
			if (ht->tables[index]._state == EXITS)
			{
				return &(ht->tables[index]);
			}
			else
			{
				return NULL;
			}
		}
		else
		{
			++index;
			if (index == ht->len)
			{
				index = 0;
			}
		}
	}
	return NULL;
}
int HTSize(HashTable* ht)
{
	assert(ht);
	return ht->size;
}
int HTEmpty(HashTable* ht)
{
	assert(ht);
	return ht->size == 0 ? 0 : 1;
}


void HashPrint(HashTable *ht)//打印数组
{
	int i = 0;
	char* strState[3] = { "EMPTY", "EXIST", "DELETE" };
	assert(ht);
	for (; i < ht->len; ++i)
	{
		printf("%s->table[%d]%s:%d\n", strState[ht->tables[i]._state], i,
			ht->tables[i]._key, ht->tables[i]._value);
	}
	printf("\n");
}

测试

#include "HashTable.h"


void HTtest2()
{
	int i = 0;
	HashNode* ret;
	char* strs[] = { "insert", "insert", "insert", "insert", "insert", "sort", "insert", "sort", "find" };
	/*char* strs[] = {"abcd", "bcad", "cbad","cbad", "aad", "abc", "acb"};*/
	HashTable ht;
	HTInit(&ht, 10);
	for (; i < sizeof(strs) / sizeof(char*); ++i)
	{
		ret = HTFind(&ht, strs[i]);
		if (ret)
		{
			ret->_value++;
		}
		else
		{
			HTInsert(&ht, strs[i], 1);
		}
	}

	HashPrint(&ht);
}





int  main()
{
	HTtest2();
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_41892460/article/details/82967752