哈希之开散列

对哈希表进行一些基本操作

源文件

#include"HashBucket.h"
#include"Prime.h"

int main()
{
	test();
	return 0;
}

//初始化哈希桶
void InitHashBucket(HT* ht, int capacity,PHF dataToInt)
{
	int BucketNo = 0;
	capacity = GetPrime(capacity);
	ht->_table = (PNode*)malloc(capacity*sizeof(Node));
	assert(ht->_table);
	//所有存放链表的地址置空
	for (int i = 0; i < capacity; i++)
	{
		ht->_table[i]=NULL;
	}
	ht->_capacity = capacity;
	ht->_size = 0;
	ht->_DateToInt = dataToInt;
}

//插入,此哈希桶中没有相同元素
int InsertHashBucketUnique(HT* ht, K key, V v)
{
	int BucketNo = 0;
	PNode pNewNode = NULL;
	PNode pCur = NULL;
	//检查是否需要扩容
	ChechCapacity(ht);
	BucketNo = HashFunc(ht, key);
	pCur = ht->_table[BucketNo];
	//查找是否有相同元素
	while (pCur)
	{
		//若有相同元素,则插入失败
		if (pCur->_data._key == key)
			return 0;
		pCur = pCur->_pNext;
	}
	//跳出循环,则没有找到相同元素,插入新结点
	//头插法
	pNewNode = BuyNode(key, v);
	pNewNode->_pNext = ht->_table[BucketNo];
	ht->_table[BucketNo] = pNewNode;
	ht->_size++;
	//插入成功
	return 1;
}

//删除,此哈希桶中没有相同元素
int DeleteHashBucketUnique(HT* ht, K key)
{
	PNode pCur = NULL;
	PNode pPrev = NULL;
	int BucketNo = 0;

	key = ht->_DateToInt(key);
	BucketNo = HashFunc(ht, key);
	pCur = ht->_table[BucketNo];
	while (pCur)
	{
		//找到元素,删除
		if (pCur->_data._key == key)
		{
			//若为头结点
			if (pCur == ht->_table[BucketNo])
				ht->_table[BucketNo] = pCur->_pNext;
			else
				pPrev->_pNext = pCur->_pNext;

			free(pCur);
			pCur = NULL;
			ht->_size--;
			//删除成功
			return 1;
		}
		//记录前一个结点
		pPrev = pCur;
		pCur = pCur->_pNext;
	}
	//找不到,删除失败
	return 0;
}

//插入元素,此哈希表中可能存在相同元素
void InsertHashBucketEqual(HT* ht, K key, V v)
{
	int BucketNo = 0;
	PNode pCur = NULL;
	//检查是否需要扩容
	key = ht->_DateToInt(key);
	ChechCapacity(ht);
	BucketNo = HashFunc(ht, key);
	pCur = BuyNode(key, v);
	//头插法
	pCur->_pNext = ht->_table[BucketNo];
	ht->_table[BucketNo] = pCur;
	ht->_size++;
}

//删除,此哈希桶中有相同元素
int DeleteHashBucketEqual(HT* ht, K key)
{
	PNode pCur = NULL;
	PNode pPrev = NULL;
	int BucketNo = HashFunc(ht, key);
	int oldsize = ht->_size;
	key = ht->_DateToInt(key);
	pCur = ht->_table[BucketNo];
	while (pCur)
	{
		//找到元素,删除
		if (pCur->_data._key == key)
		{
			//若为头结点
			if (pCur == ht->_table[BucketNo])
			{
				ht->_table[BucketNo] = pCur->_pNext;
				free(pCur);
				pCur = ht->_table[BucketNo];
			}
			else
			{
				pPrev->_pNext = pCur->_pNext;
				free(pCur);
				pCur = pPrev->_pNext;
			}
			ht->_size--;
		}
		else
		{
			//记录前一个结点
			pPrev = pCur;
			pCur = pCur->_pNext;
		}
	}
	//删除成功
	if (oldsize - (ht->_size) > 0)
		return 1;
	//没找到或删除失败
	else
		return 0;
}

//查找
PNode FindHashBucket(HT* ht, K key)
{
	int BucketNo = 0;
	PNode pCur = NULL;

	if (NULL==ht)
		return 0;

	key = ht->_DateToInt(key);
	BucketNo = HashFunc(ht, key);
	pCur = ht->_table[BucketNo];
	while (pCur)
	{
		if (pCur->_data._key == key)
			return pCur;
		pCur = pCur->_pNext;
	}
	//找不到,返回0
	return 0;
}

//扩容
int ChechCapacity(HT* ht)
{
	//扩容条件
	if (ht->_capacity == ht->_size)
	{
		unsigned long newcapacity = GetPrime(ht->_capacity);
		PNode pCur = NULL;
		int NewBacketNo = 0;
		//创建一个新的哈希桶
		PNode* newtable = (PNode*)malloc(sizeof(Node)*newcapacity);
		assert(newtable);
		//将原哈希桶中数据转移到新的哈希桶中
		//遍历原哈希桶
		for (unsigned long i = 0; i < ht->_capacity; i++)
		{
			pCur = ht->_table[i];
			while (pCur)
			{
				//计算新桶号
				NewBacketNo = pCur->_data._key%newcapacity;
				//头插,取出pCur放入新桶中
				ht->_table[i] = pCur->_pNext;
				pCur->_pNext = newtable[NewBacketNo];
				newtable[NewBacketNo] = pCur;
				//返回原哈希表的下一个结点
				pCur = ht->_table[i];
			}
		}
		//释放原哈希桶
		free(ht->_table);
		ht->_table = newtable;
		//更新容量
		ht->_capacity = newcapacity;
		return 1;
	}
	else
		return 0;
}

//销毁
void DestroyHashBucket(HT* ht)
{
	PNode pCur = NULL;
	for (unsigned long i = 0; i < ht->_capacity; i++)
	{
		pCur = ht->_table[i];
		while (pCur)
		{
			ht->_table[i] = pCur->_pNext;
			free(pCur);
			pCur = ht->_table[i];
		}
	}
	free(ht->_table);
	ht->_table = NULL;
}

//哈希函数
int HashFunc(HT* ht, K key)
{
	return key%ht->_capacity;
}

//创建新结点
PNode BuyNode(K key, V value)
{
	PNode  pNewNode = (PNode)malloc(sizeof(Node));
	assert(pNewNode);
	pNewNode->_pNext = NULL;
	pNewNode->_data._key = key;
	pNewNode->_data._value = value;

	return pNewNode;
}

//打印哈希桶
void PrintHashBucket(HT* ht)
{
	PNode pCur = NULL;
	for (unsigned long i = 0; i < ht->_capacity; i++)
	{
		pCur = ht->_table[i];
		while (pCur)
		{
			printf("Table[%d] :(%d) (%d)", i, pCur->_data._key, pCur->_data._value);
			printf("\n");
			pCur = pCur->_pNext;
		}
	}
	printf("\n");
}

//字符串转化成整型函数
 size_t BKDRHash(const char * str)
{
unsigned int seed = 131; // 31 131 1313
unsigned int hash = 0;
while (*str)
{
hash = hash * seed + (*str++);
}
return (hash & 0x7FFFFFFF);
}


//数据转化成整型函数
 size_t DataToInt(K key)
{
return key;
}
void test()
{
HT ht;
InitHashBucket(&ht, 10, DataToInt);
InsertHashBucketEqual(&ht, 12, 20);
InsertHashBucketEqual(&ht, 30, 20);
InsertHashBucketEqual(&ht, 40, 20);
InsertHashBucketEqual(&ht, 40, 20);
PrintHashBucket(&ht);


InsertHashBucketUnique(&ht, 30, 20);
InsertHashBucketUnique(&ht, 41, 22);
PrintHashBucket(&ht);


DeleteHashBucketUnique(&ht, 30);
DeleteHashBucketEqual(&ht, 40);
PrintHashBucket(&ht);


DestroyHashBucket(&ht);
system("pause");
}

头文件

#include<malloc.h>
#include<assert.h>
#include<stdio.h>


typedef int K;
typedef int V;
typedef (*PHF)(K);  //函数指针

typedef struct Pair
{
	K _key;
	V _value;
}Pair;

typedef struct Node
{
	struct Node* _pNext;
	Pair _data;
}Node, *PNode;


typedef struct HashTable
{
	PNode* _table;
	unsigned long _capacity;
	unsigned long _size;
	PHF _DateToInt;
}HT;



void InitHashBucket(HT* ht, int capacity,PHF dataToInt);
int InsertHashBucketUnique(HT* ht, K key, V v);
int DeleteHashBucketUnique(HT* ht, K key);

void InsertHashBucketEqual(HT* ht, K key, V v);
int DeleteHashBucketEqual(HT* ht, K key);
PNode FindHashBucket(HT* ht, K key);
int ChechCapacity(HT* ht);
void DestroyHashBucket(HT* ht);

int HashFunc(HT* ht, K key);
PNode BuyNode(K key, V value);
void PrintHashBucket(HT* ht);
void test();
此外,还用了一个计算素数容量的函数
#define  _PrimeSize 28
static const unsigned long _PrimeList[_PrimeSize] =
{
	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
};

unsigned long GetPrime(unsigned long capacity);
#include "Prime.h"

unsigned long GetPrime(unsigned long capacity)
{
	unsigned long i = 0;
	for (; i < _PrimeSize; i++)
	{
		if (capacity < _PrimeList[i])
			return _PrimeList[i];
	}
	return _PrimeList[_PrimeSize - 1];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值