PracticeDev/study_cpp/hashmap_test/hash_map_test.cpp

195 lines
4.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include<iostream>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
#define HARSH_TABLE_MAX_SIZE (1000) // 哈希数组的最大元素个数
typedef struct HarshNode_struct HarshNode;
// 定义一个哈希表的节点
struct HarshNode_struct
{
char * sKey; // [sKey,nvalue]是一对键值对
int nValue;
HarshNode *pNext;
};
HarshNode * harshTable[HARSH_TABLE_MAX_SIZE]; // 哈希表数组
unsigned int g_harsh_table_size = 0x0;
//初始化哈希表
void harsh_table_init(void)
{
int i = 0x0;
memset(harshTable,0,sizeof(HarshNode *)*HARSH_TABLE_MAX_SIZE);
g_harsh_table_size = 0x0;
}
// string harsh function
unsigned int harsh_table_harsh_string(const char * sKey)
{
const unsigned char* p = (const unsigned char*) sKey;
unsigned int value = *p;
if(value)
{
for( p += 1; *p != '\0'; p++)
{
value = (value << 5) - value + *p;
}
}
return value;
}
//根据键值对向哈希表中添加节点如果skey已经存在则直接更新键值nValue
//添加成功返回0添加失败返回-1
int harsh_table_insert_node(const char * sKey, int nValue)
{
HarshNode * pHarshNodeHead = NULL;
HarshNode * pNewNode = NULL;
unsigned int pos = 0x0;
if((g_harsh_table_size >= HARSH_TABLE_MAX_SIZE )||(NULL == sKey))
return -1;
pos = harsh_table_harsh_string(sKey) % HARSH_TABLE_MAX_SIZE; //用这种方法计算sKey在哈希数组中对应的位置
printf("harsh_table_insert_node : pos = %d\n",pos);
pHarshNodeHead = harshTable[pos];
if(NULL == pHarshNodeHead)
printf("harsh_table_insert_node:NULL == pHarshNodeHead\n");
while(NULL != pHarshNodeHead ) // 如果这个位置对应的不是这一串中最后一个节点的话,那就要向后移动了
{
if(strcmp(pHarshNodeHead->sKey,sKey) == 0) //如果这个键值对已经存在,只更新键值即可
{
pHarshNodeHead ->nValue = nValue;
return 0;
}
pHarshNodeHead = pHarshNodeHead->pNext; //向后移动,肯定会有NULL的时候
}
pNewNode = (HarshNode *)malloc(sizeof(HarshNode)); //申请一块HarshNode 大小的内存
if(NULL == pNewNode)
{
return -1;
}
memset(pNewNode,0,sizeof(HarshNode));
pNewNode ->sKey = (char *)malloc(strlen(sKey) + 1); //申请一块sKey大小的内存
if(NULL == pNewNode ->sKey )
{
return -1;
}
memset(pNewNode ->sKey,0,strlen(sKey) + 1);
strcpy(pNewNode ->sKey,sKey); //将sKey的内容赋给 pNewNode -> sKey
pNewNode ->nValue = nValue; //键值也复制过来
pNewNode ->pNext = NULL; //由于是新节点也是尾节点所以pNext指向NULL
pHarshNodeHead = pNewNode;
harshTable[pos] = pHarshNodeHead; //最后一定要让数组中的这个位置指向这个头指针
g_harsh_table_size ++;
return 0;
}
//打印数组中对应的某个位置的那一串哈希值
void print_harsh_node(int pos)
{
HarshNode * pHarshNodeHead = NULL;
if(pos >= HARSH_TABLE_MAX_SIZE)
return;
pHarshNodeHead = harshTable[pos];
if(NULL == pHarshNodeHead)
printf("NULL == pHarshNodeHead\n");
while(NULL != pHarshNodeHead)
{
printf("come here \n");
printf("Position:%d, sKey:%s, nValue:%d \n",pos,pHarshNodeHead->sKey,pHarshNodeHead->nValue);
pHarshNodeHead = pHarshNodeHead->pNext;
}
}
// 根据键值sKey来查找对应的哈希节点
HarshNode * harsh_table_lookup(const char *sKey)
{
unsigned int pos = 0x0;
HarshNode * pHarshHead = NULL;
if(NULL == sKey)
{
return NULL;
}
pos = harsh_table_harsh_string(sKey) % HARSH_TABLE_MAX_SIZE; //计算出在哈希数组中的位置
pHarshHead = harshTable[pos];
while(NULL != pHarshHead)
{
if(strcmp(sKey,pHarshHead->sKey) == 0)//找到了
return pHarshHead;
pHarshHead = pHarshHead->pNext; // 没有找到的话来到下一个节点
}
return NULL;
}
int main(void)
{
char * pSkey = "abcd";
int nValue = 1234;
int ret = -1;
int pos = 0xffffffff;
HarshNode * pHarshNode = NULL;
harsh_table_init();
ret = harsh_table_insert_node(pSkey,nValue);
printf("ret = %d\n",ret);
if(!ret)
{
pos = harsh_table_harsh_string(pSkey) % HARSH_TABLE_MAX_SIZE;
printf("main: pos = %d\n",pos);
print_harsh_node(pos);
}
pHarshNode = harsh_table_lookup(pSkey);
if(NULL != pHarshNode)
{
printf("Got it: sKey:%s, nValue: %d\n",pHarshNode->sKey,pHarshNode->nValue);
}
return 0;
}