动态哈希表

动态哈希表的基本操作

 

函数实现部分

 

void InitHashBucket(HT* ht, int capacity)//初始化哈希表

{

if (ht == NULL)

{

return;

}

// 获取容量

capacity = GetPrime(capacity);

ht->table = (PNode*)malloc(sizeof(Node)*capacity);

//哈希表的初始化

for (int i = 0; i < ht->capacity; i++)

{

ht->table[i] = NULL;

}

//容量和元素个数

ht->size = 0;

ht->capacity = capacity;

}

 

 

int InsertHashBucketUnique(HT* ht, K key, V v)//插入不同的数据

{

if (NULL == ht)

{

return;

}

    ChechCapacity(ht);

//数据是否在表中

int num = HashFunc(ht, key);

PNode pcur = ht->table[num];

while (pcur)//不为空

{

if (pcur->_data._key == key)//已经存在,不需要再插入

{

return;//返回

}

pcur = pcur->_pNext;

 

}

//如果为空,则创建新节点

 

PNode pnewnode = BuyNode(key, v);//创建新节点

pnewnode->_pNext = ht->table[num];//将其插入

ht->size++;

}

 

int DeleteHashBucketUnique(HT* ht, K key)//删除不同的数

{

if (NULL == ht)

{

return;

}

int num = HashFunc(ht, key);

PNode pcur = ht->table[num];

PNode prev = NULL;

while (pcur)

{

if (pcur->_data._key == key)

{

prev->_pNext = pcur->_pNext;

free(pcur);

return 1;//找到了

}

prev = pcur;//记录prev

pcur = pcur->_pNext;

ht->size--;

}

return 0;

}

 

 

int DeleteHashBucketEqual(HT* ht, K key)//删除相同的数,2,22,2,2,32,4

{

if (NULL == ht)

{

return;

}

int num = HashFunc(ht, key);

PNode pcur = ht->table[num];

PNode prev = NULL;

while (pcur)

{

if (pcur->_data._key == key)

{

if (pcur == ht->table[num])//在头部,进行头删

{

ht->table[num] = pcur->_pNext;//将22放到头部

free(pcur);

pcur = ht->table[num];

//指向22

return 1;

}

prev = pcur;

prev->_pNext = pcur->_pNext;

}

prev = pcur;//记录prev

pcur = pcur->_pNext;

prev->_pNext = pcur->_pNext;

        ht->size--;

}

return 0;

}

PNode FindHashBucket(HT* ht, K key)//查找

{

if (NULL == ht)

{

return;

}

int num = HashFunc(ht, key);

PNode pcur = ht->table[num];

    while (pcur)

{

if (pcur->_data._key == key)

{

return pcur;

}

pcur = pcur->_pNext;//后移

return 0;

}

}

int ChechCapacity(HT* ht)//扩容

{

if (NULL == ht)

{

return;

}

//开辟新空间

if (ht->size == ht->capacity)

{

int i = 0;

unsigned long newcapacity = GetPrime(ht->capacity);

PNode *NewTable = (PNode*)malloc(sizeof(PNode)*newcapacity);

if (NULL == NewTable)

{

return 0;

}

//拷贝元素

for (i = 0; i < ht->capacity; i++)

{

if (ht->table)//先将旧哈希表中的数据取出来

{

PNode pcur = ht->table[i];

while (pcur)

{

int num = (int)pcur->_data._key%newcapacity;

ht->table[i] = pcur->_pNext;//取出旧表中的头

pcur->_pNext = NewTable[num];//指向新的表

NewTable[num] = pcur;//将值给过去

pcur = ht->table[i];//改变旧表中的头

}

 

}

}

//释放旧空间

ht->table = NewTable;

ht->capacity = newcapacity;//更新容量

free(ht->table);

return 1;

}

}

 

 

 

void DestroyHashBucket(HT* ht)//销毁哈希表

{

if (ht == NULL)

{

return;

}

for (int num = 0; num < ht->capacity; num++)

{

PNode pcur = ht->table[num];//删除每个桶中的元素

while (pcur)

{

ht->table[num] = pcur->_pNext;

free(pcur);

pcur = pcur->_pNext;

}

 

}

}

 

 

int HashFunc(HT* ht, K key)//哈希函数

{

PNode pcur = ht->table;

return (int)(pcur->_data._key) % (ht->capacity);

}

PNode BuyNode(K key, V value)//创建新节点

{

PNode pnewnode = (PNode*)malloc(sizeof(Node));//开辟空间

return pnewnode;

}

void PrintHashBucket(HT* ht)//打印哈希表

{

if (ht == NULL)

{

return;

}

for (int i = 0; i < ht->capacity; i++)

{

PNode pcur = ht->table[i];

while (pcur)

{

printf("d%,d%->", pcur->_data._key, pcur->_data._key);

 

}

printf("NULL\n");

}

}

unsigned long GetPrime( int data)//获取容量

{

for (int i = 0; i<_PrimeSize;i++)

 

{

if (_PrimeList[i]>data)

 

{

 

data = _PrimeList[i];

 

}

 

}

 

return data;

 

}

 

 

头文件

 

#include"stdio.h"

#include"assert.h"

#include"malloc.h"

 

typedef char* K;

typedef char* V;

 

typedef struct Pair

{

K _key;

V _value;

}Pair;

 

 

typedef (*phf)(int);

typedef struct Node

{

struct Node* _pNext;

Pair _data;

}Node, *PNode;

 

 

typedef struct HashTable

{

PNode* table;

unsigned long capacity;

unsigned long size;

}HT;

 

 

#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

 

};

 

 

 

 

//////////////////////////////////////////////////////////

// .h

void InitHashBucket(HT* ht, int capacity);

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);

unsigned long GetPrime(int data);

 

 

 

 

 

测试函数

 

#include"HT.h"

 

int main()

{

HT ht;

int capacity = 0;

InitHashBucket(&ht,capacity);

InsertHashBucketUnique(&ht, 11,1);

InsertHashBucketUnique(&ht, 12,2);

InsertHashBucketUnique(&ht, 22, 2);

InsertHashBucketUnique(&ht, 67, 7);

 

PrintHashBucket(&ht);

DeleteHashBucketUnique(&ht,22);

    FindHashBucket(& ht, 67);

FindHashBucket(&ht, 78);

 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

### 动态哈希表的时间复杂度分析 #### 插入操作 对于动态哈希表而言,插入新元素的操作通常情况下可以在常量时间内完成。这是因为哈希函数能够快速定位到存储位置,并将元素放置于该处。然而,在某些特殊情形下——例如当发生严重的哈希碰撞或是达到预设的负载阈值触发自动扩展机制时,则可能涉及到额外的工作,如重新计算现有元素的位置并迁移它们至新的更大的空间内[^1]。 ```python def insert(hash_table, key, value): index = hash_function(key) if not is_full(hash_table): # 如果未满则直接插入 add_to_bucket(hash_table[index], (key, value)) else: # 否则先扩容再插入 resize_and_rehash(hash_table) add_to_bucket(hash_table[hash_function(key)], (key, value)) ``` #### 删除操作 删除指定键对应的条目同样期望能在 O(1) 的平均时间里实现。具体来说就是利用哈希码找到目标桶位之后沿着潜在存在的链表遍历直至发现匹配项为止;一旦找到了就将其移除。不过需要注意的是如果被删节点位于较长链条之中的话可能会消耗更多资源去追踪路径直到终点[^2]。 ```python def delete(hash_table, key): index = hash_function(key) bucket = hash_table[index] prev_node = None current_node = find_in_bucket(bucket, key) while current_node and current_node.key != key: prev_node = current_node current_node = next(current_node) if current_node: remove_from_bucket(prev_node, current_node) ``` #### 查找查询 查找给定关键字的过程也遵循类似的逻辑模式,即借助高效的散列算法迅速锁定候选集合进而实施局部检索工作。理想状态下整个流程仅需固定数量级的动作就能达成目的。但是考虑到实际应用环境中不可避免的存在着一定概率下的冲突现象所以最坏情况下的性能表现会有所下降[^3]。 ```python def search(hash_table, key): index = hash_function(key) bucket = hash_table[index] node = find_in_bucket(bucket, key) return node.value if node else None ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值