Hash表的研究(1)

一个简单的自己写的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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值