C Hash表--链地址法

/**
 * 已知一组关键字为{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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值