一个简单的自己写的HASH的例子:
/*******************************************************************************
Hash by hmily on 2011-7-13
*******************************************************************************/
#include <stdio.h>
#include <assert.h>
/* 双向链表 */
typedef struct tagNode_S{
struct tagNode_S *pstNext;
struct tagNode_S *pstPrev;
}Node_S;
#define ERROR 0
#define OK 1
typedef struct tagList_S{
Node_S Head;
int iNumber;
}List_S;
typedef struct tagHashTable_S
{
int iCount;
List_S stList[1];
}HashTable_S;
typedef struct tagData_S
{
Node_S stNode;
int iName;
int iNumber;
int iAdderss;
}Data_S;
#define ListAdd(List,pNode) \
(pNode)->pstNext = &((List).Head);\
(pNode)->pstPrev = (List).Head.pstNext;\
(List).Head.pstPrev->pstNext = (pNode);\
(List).Head.pstPrev = (pNode);\
(List).iNumber ++;
#define ListDel(List,pNode) \
(pNode)->pstPrev->pstNext = (pNode)->pstNext;\
(pNode)->pstNext->pstPrev = (pNode)->pstPrev;\
(List).iNumber--;
#define ListInit(List) \
(List).iNumber = 0;\
(List).Head.pstNext = &((List).Head);\
(List).Head.pstPrev = &((List).Head);
/* 单项链表 */
#define MAX 1000
#define Invaild 0xffffffff
/* 散列表的数据 */
int initHashTable(HashTable_S **ppstHashTable)
{
int i = 0;
*ppstHashTable = (HashTable_S *)malloc(sizeof(HashTable_S) + (MAX - 1) * sizeof(List_S));
if (NULL == *ppstHashTable)
{
assert(0);
return ERROR;
}
(*ppstHashTable)->iCount = MAX;
for (;i < MAX; i++)
{
ListInit((*ppstHashTable)->stList[i]);
}
return OK;
}
int GetKeyHashTable(int iName)
{
return iName % MAX;
}
int FindNodeFromHashTalbe(int iName, HashTable_S *pstHashTable, Data_S **ppstData)
{
int iKey = 0;
int i = 0;
Data_S *pstTemp = NULL;
if (NULL == pstHashTable)
{
assert(0);
return ERROR;
}
iKey = GetKeyHashTable(iName);
if (0 == pstHashTable->stList[iKey].iNumber)
{
//printf("\r\nsorry,can not find %d,data is NULL",iName);
return OK;
}
/* 获取第一个 */
pstTemp = (Data_S *)(pstHashTable->stList[iKey].Head.pstNext);
for(;i < pstHashTable->stList[iKey].iNumber;i++)
{
if ((NULL == pstTemp)||(&(pstHashTable->stList[iKey].Head)== (Node_S *)pstTemp))
{
assert(0);
return ERROR;
}
if (pstTemp->iName == iName)
{
*ppstData = pstTemp;
return OK;
}
pstTemp = (Data_S *)(pstTemp->stNode.pstNext);
}
//printf("\r\nsorry,can not find %d",iName);
return OK;
}
int read(FILE *fpInput)
{
char chNum[20]={};
char *pchTemp = chNum;
char chp;
int j = 0;
int i = 0;
int iRet = 0;
chp = fgetc(fpInput);
if (EOF == chp)
{
return Invaild;
}
while (chp != ',')
{
*pchTemp = chp - '0';
pchTemp ++;
i++;
chp = fgetc(fpInput);
if (EOF == chp)
{
break;
}
}
j = 1;
while(i > 0)
{
iRet += chNum[i-1] * j;
i--;
j = j*10;
}
return iRet;
}
void write(int chp, int iCount,FILE *fpOutput)
{
char chOutput[100] = {0};
char *chpRead = chOutput;
if((EOF == chp) || (0 == iCount) || (NULL == fpOutput))
{
assert(0);
return;
}
(void)sprintf(chOutput,"%c,%u",chp,iCount);
while('\0' != *chpRead)
{
(void)fputc(*chpRead,fpOutput);
chpRead++;
}
return;
}
void writestring(char *pchStr,FILE *fpOutput)
{
char *chpRead = NULL;
if((NULL == pchStr) || (NULL == fpOutput))
{
assert(0);
return;
}
chpRead = pchStr;
while('\0' != *chpRead)
{
(void)fputc(*chpRead,fpOutput);
chpRead++;
}
return;
}
void FreeNode(HashTable_S **ppstHashTable)
{
int i = 0;
int j = 0;
Data_S *pstTemp = NULL;
Node_S *pstDelNode = NULL;
if (NULL == *ppstHashTable)
{
return;
}
for (i = 0;i < MAX ; i++)
{
while(0 != (*ppstHashTable)->stList[i].iNumber)
{
pstDelNode = (*ppstHashTable)->stList[i].Head.pstNext;
if (NULL == pstDelNode)
{
assert(0);
}
ListDel((*ppstHashTable)->stList[i],pstDelNode);
pstTemp = (Data_S *)pstDelNode;
free(pstTemp);
pstTemp = NULL;
pstDelNode = NULL;
}
}
free(*ppstHashTable);
*ppstHashTable = NULL;
}
void process(FILE *fpInput, FILE *fpOutput)
{
char chp;
int iRead;
int iCount = 0;
Data_S *pstData = NULL;
int iKey = 0;
HashTable_S *pstHashTable = NULL;
int iRet = OK;
int i = 0;
int j = 0;
int iSaveNum = 0;
char choutput[1000] ={0};
Data_S *pstTemp = NULL;
if ((NULL == fpInput)||(NULL == fpOutput))
{
assert(0);
goto EXIT;
}
/* 初始化对应的HASH */
iRet = initHashTable(&pstHashTable);
if (OK != iRet)
{
assert(0);
goto EXIT;
}
/* 读取数据 */
//printf("\r\nread data is ....");
while((iRead = read(fpInput)) != Invaild)
{
//printf("\r\n Read data =%u,",iRead);
iCount ++;
/* 找到对应的KEY */
iKey = GetKeyHashTable(iRead);
/* 查询链表里是否有相同的数据 */
iRet = FindNodeFromHashTalbe(iRead,pstHashTable,&pstData);
if (OK != iRet)
{
assert(0);
goto EXIT;
}
if (NULL != pstData)
{
pstData->iNumber++;
continue;
}
/* 添加新的数据 */
/* 赋值 */
pstData = (Data_S *)malloc(sizeof(Data_S));
if (NULL == pstData)
{
assert(0);
goto EXIT;
}
memset(pstData, sizeof(Data_S), 0);
pstData->iAdderss = iCount;
pstData->iName = iRead;
pstData->iNumber = 1;
/* 添加到对应的链表中 */
ListAdd((pstHashTable->stList[iKey]),((Node_S *)pstData));
//printf("\r\n add data[%d] is success",iRead);
pstData = NULL;
}
/* 写数据 */
//printf("\r\n Output data is begin.....");
sprintf(choutput,"\r\n Output data is begin.....");
//writestring("\r\n Output data is begin.....",fpOutput);
writestring(choutput,fpOutput);
for (i = 0;i < MAX;i++)
{
sprintf(choutput, "\r\nThere is index[%d]......:\r\n",i);
writestring(choutput,fpOutput);
pstTemp = (Data_S *)(pstHashTable->stList[i].Head.pstNext);
for(j = 0;j < pstHashTable->stList[i].iNumber; j++)
{
sprintf(choutput, "\r\n Data[%d] Name=%d,count=%d,address=%d",
j,pstTemp->iName,pstTemp->iNumber,pstTemp->iAdderss);
writestring(choutput,fpOutput);
iSaveNum += pstTemp->iNumber;
pstTemp = (Data_S *)pstTemp->stNode.pstNext;
}
}
//write(char chp, int iCount, FILE * fpOutput);
EXIT:
/* 释放资源 */
FreeNode(&pstHashTable);
printf("\r\n Output Num is %d",iSaveNum);
return;
}
int main()
{
FILE *fpInput = NULL;
FILE *fpOutput = NULL;
char a[30]={0};
unsigned int i;
int iNum = 99999999;
char *cpTemp = a;
printf("int sizeof is %u",sizeof(int));
/* 输入数据 */
fpInput = fopen("1.txt","w");
if (NULL == fpInput)
{
printf("read 1.txt is error!");
goto End;
}
for(;iNum > 0;iNum--)
{
i = rand();
if (1 == iNum)
{
sprintf(a,"%u",i);
}
else
{
sprintf(a,"%u,",i);
}
cpTemp = a;
while('\0' != *cpTemp)
{
(void)fputc(*cpTemp,fpInput);
cpTemp++;
}
}
fclose(fpInput);
/* 读取数据 */
fpInput = fopen("1.txt","rb");
if (NULL == fpInput)
{
printf("read 1.txt is error!");
goto End;
}
/* 写数据 */
fpOutput = fopen("2.txt","w");
if (NULL == fpOutput)
{
printf("read 2.txt is error!");
goto End;
}
(void)process(fpInput, fpOutput);
//for(i=0;i<20;i++)
//fgets(a,2,fp);
fclose(fpOutput);
fclose(fpInput);
End:
system("pause");
return 0;
}