/**
* 已知一组关键字为{19, 14, 23, 01, 68, 20, 84, 27, 55, 11, 10, 79},
* 按Hash函数为H(key) = key MOD 13和链地址法处理冲突构造Hash表。
* 结果如图:
* Hash[0]
* Hash[1]-->01-->14-->27-->70-->null
* Hash[2]
* Hash[3]-->55-->68-->null
* Hash[4]
* Hash[5]
* Hash[6]-->19-->84-->null
* Hash[7]-->20-->null
* Hash[8]
* Hash[9]
* Hash[10]-->10-->23-->null
* Hash[11]-->11-->null
* Hash[12]
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#define HTABLE_SIZE (13)
#define HTABLE_ALG (13) /* 用于Hash函数取余数 */
typedef int ElementType ;
/* 记录 */
typedef struct tagStNode
{
int iKey; /* 记录关键字 */
ElementType others; /* 其他任意数据 */
struct tagStNode *pstNext;
}StNode;
/* Hash表 */
typedef struct tagStHTable
{
StNode astHTable[HTABLE_SIZE]; /* Hash表 */
int iCount; /*当前Hash表中的元素个数 */
}StHTable;
/* Hash函数
* H(key) = key MOD 13
* */
int HashFunc(int iNum);
/* 打印Hash表 */
void PrintHTable(StHTable *pstHTable);
/* 将值为iNum的节点存入Hash表中 */
int StoreNum2HTable(StHTable *pstHTable, int iNum);
/* Hash函数 */
int HashFunc(int iNum)
{
return iNum % HTABLE_ALG;
}
/* 将值为iNum的节点存入Hash表中 */
int StoreNum2HTable(StHTable *pstHTable, int iNum)
{
int iLocate = -1;
StNode *pstHead = NULL;
StNode *pstTmpNode = NULL;
StNode *pstP = NULL;
StNode *pstQ = NULL;
assert(NULL != pstHTable);
iLocate = HashFunc(iNum); /* Hash映射函数 */
pstHead = &pstHTable->astHTable[iLocate]; /* Hash表某一散列位置的头指针 */
/* 没有冲突时 */
if (NULL == pstHead->pstNext)
{
/* 分配一个数据节点并初始化 */
pstTmpNode = (StNode *)malloc(sizeof(StNode));
assert(NULL != pstTmpNode);
pstTmpNode->iKey = iNum;
pstTmpNode->pstNext = NULL;
/* 将该数据节点插入Hash表中 */
pstHead->pstNext = pstTmpNode;
}
/* 存在冲突时,直接插入链表尾部 */
else
{
/* 分配一个数据节点并初始化 */
pstTmpNode = (StNode *)malloc(sizeof(StNode));
assert(NULL != pstTmpNode);
pstTmpNode->iKey = iNum;
pstTmpNode->pstNext = NULL;
#if 0
/* 每次将节点插入链表尾部 */
pstP = pstHead->pstNext;
while (NULL != pstP->pstNext) /* pstP用于指向某一链表的最后一个节点 */
{
pstP = pstP->pstNext;
}
/* 将数据节点插入Hash表中某一链表的最后 */
pstP->pstNext = pstTmpNode;
#else
/* 按从小到大的顺序插入 */
pstP = pstHead->pstNext;
pstQ = pstHead; /* pstQ用于指向pstP前一个节点,主要是方便插入节点 */
while (NULL != pstP)
{
if (pstP->iKey <= pstTmpNode->iKey)
{
pstQ = pstP;
pstP = pstP->pstNext;
}
else
{
break;
}
}
/* 插入新节点 */
pstTmpNode->pstNext = pstQ->pstNext;
pstQ->pstNext = pstTmpNode;
}
#endif
return 0;
}
/* 打印Hash表 */
void PrintHTable(StHTable *pstHTable)
{
StNode *pstHead = NULL;
int iCount = 0;
assert(NULL != pstHTable);
for (; iCount < HTABLE_SIZE; iCount++)
{
printf("Hash[%d]---", iCount);
pstHead = &pstHTable->astHTable[iCount];
pstHead = pstHead->pstNext;
while (NULL != pstHead)
{
printf("Value[%d] ", pstHead->iKey);
pstHead = pstHead->pstNext;
}
printf("\n");
}
return ;
}
/* 主函数 */
int main(int argc, char **argv)
{
int aiArry[] = {19, 14, 23, 01, 68, 20, 84, 27, 55, 11, 10, 79, 0}; /* 测试序列 */
// int aiArry[] = {14, 1, 27,14, 79}; /* used for test */
int iArryLen = sizeof(aiArry)/sizeof(int);
int iCount = 0;
StHTable stHTable;
memset(&stHTable, 0, sizeof(StHTable));
for (; iCount < iArryLen; iCount++)
{
StoreNum2HTable(&stHTable, aiArry[iCount]);
}
PrintHTable(&stHTable);
return 0;
}
C Hash表--链地址法
最新推荐文章于 2025-05-08 14:14:48 发布