ハッシュのハッシュ

18601 ワード

HashBucett.

#pragma once

#include 
#include 
#include 
#include 

//#include "Common.h"
#define  size_t unsigned long

typedef int DataType;
//typedef char* DataType;

//  Int    
typedef size_t(*PDT)(DataType data);


typedef struct Node
{
    struct Node* _pNext;
    DataType _data;
}Node, *PNode;

//   
typedef struct HashBucket
{
    PNode * _table;
    int _capacity;      //    
    int _size;          //    
    PDT  _setData;      //        ,
}HashBucket;


//      
void HashBucketInit(HashBucket* ht, int capacity, PDT  _setData);

//          
void HashBucketInsertUnique(HashBucket* ht, DataType data);
void HashBucketDeleteUnique(HashBucket* ht, DataType data);

//     
void HashBucketInsert(HashBucket* ht, DataType data);
void HashBucketDelete(HashBucket* ht, DataType data);

//  
PNode HashBucketFind(HashBucket* ht, DataType data);

//    
int HashBucketSize(HashBucket*ht);

//  
void DestroyHashBucket(HashBucket* ht);

/////////////////////////////////////////////
//    

//    
int HashFunc(HashBucket* ht, int data);

//     
PNode BuyNode(DataType data);
//  
void     HashBucketPrint(HashBucket* ht);

size_t StrToInt(const char * str);

size_t DataToInt(int data);

//  
void TestData();
void TestStr();
HashBucett.

#include "HashBucket.h"

//      
void HashBucketInit(HashBucket* ht, int capacity, PDT setData)
{
    assert(ht);
    //capacity = GetCapacity(capacity);

    ht->_table = (PNode*)malloc(sizeof(Node)*capacity);
    if (NULL == ht->_table)
        assert(0), exit(1);

    ht->_capacity = capacity;
    ht->_size = 0;
    ht->_setData = setData;

    for (int i = 0; i < ht->_capacity; i++)
    {
        ht->_table[i] = NULL;
    }
}

//     
void HashBucketInsertUnique(HashBucket* ht, DataType data)
{
    int HashAddr = -1;
    assert(ht);

    int Newdata = ht->_setData(data);
    HashAddr = HashFunc(ht, Newdata);


    //       
    PNode pCur = ht->_table[HashAddr];

    while (pCur)
    {
        if (pCur->_data == data)
            return;
        else
            pCur = pCur->_pNext;
    }

    //  
    pCur = BuyNode(data);

    pCur->_pNext = ht->_table[HashAddr];
    ht->_table[HashAddr]= pCur;
    ht->_size++;
}

//     
void HashBucketDeleteUnique(HashBucket* ht, DataType data)
{
    int HashAddr = -1;
    PNode pPre = NULL;
    PNode pCur = NULL;

    assert(ht);
    int Newdata = ht->_setData(data);
    HashAddr = HashFunc(ht, Newdata);

    //   
    if (ht->_table[HashAddr] == NULL)
        return;

     pPre = ht->_table[HashAddr];
     pCur = ht->_table[HashAddr];

    //     data  
    if (pCur->_data == data)
    {
        ht->_table[HashAddr] = pCur->_pNext;
        free(pCur);
        ht->_size--;
        return;
    }

    while (pCur)
    {
        if (pCur->_data == data)
        {
            break;
        }
        else
        {
            pPre = pCur;
            pCur = pCur->_pNext;
        }
    }

    //      pCur    ,     data
    //pCur    while  
    if (pCur)
    {
        pPre->_pNext = pCur->_pNext;
        ht->_size--;
        free(pCur);
    }
}



//     
void HashBucketInsert(HashBucket* ht, DataType data)
{

    int HashAddr = -1;
    assert(ht);

    int Newdata = ht->_setData(data);
    HashAddr = HashFunc(ht, Newdata);

    //  
    PNode pCur = BuyNode(data);
    pCur->_pNext = ht->_table[HashAddr];
    ht->_table[HashAddr] = pCur;
    ht->_size++;
}

//    data   
void HashBucketDelete(HashBucket* ht, DataType data)
{
    int HashAddr = -1;
    PNode pPre = NULL;
    PNode pCur = NULL;
    assert(ht);

    int Newdata = ht->_setData(data);
    HashAddr = HashFunc(ht, Newdata);

    //   
    if (ht->_table[HashAddr] == NULL)
        return;

     pPre = ht->_table[HashAddr];
     pCur = ht->_table[HashAddr];

    //      data  
    while (pCur&&pCur->_data == data)
    {
        ht->_table[HashAddr] = pCur->_pNext;
        free(pCur);
        ht->_size--;

        pCur = ht->_table[HashAddr];
    }

    //       ,pCur    ,      
    while (pCur)
    {
        if (pCur->_data == data)
        {
            pPre->_pNext = pCur->_pNext;
            ht->_size--;
            free(pCur);
            pCur = pPre->_pNext;
        }
        else
        {
            pPre = pCur;
            pCur = pCur->_pNext;
        }
    }

}


//  
PNode HashBucketFind(HashBucket* ht, DataType data)
{
    int HashAddr = -1;
    assert(ht);

    int Newdata = ht->_setData(data);
    HashAddr = HashFunc(ht, Newdata);

    PNode pCur = ht->_table[HashAddr];
    while (pCur)
    {
        if (pCur->_data == data)
            break;
        else
            pCur = pCur->_pNext;
    }

    return pCur;
}

//    
int HashBucketSize(HashBucket*ht)
{
    return ht->_size;
}

//  
void DestroyHashBucket(HashBucket* ht)
{
    assert(ht);

    PNode pDel = NULL;

    for (int i = 0; i < ht->_capacity; ++i)
    {
        pDel = ht->_table[i]->_pNext;
        while (pDel)
        {
            ht->_table[i]->_pNext = pDel->_pNext;
            free(pDel);
            pDel = ht->_table[i]->_pNext;
        }
    }

    free(ht->_table);
    ht->_size = 0;
    ht->_capacity = 0;
}

//    
int HashFunc(HashBucket* ht, int data)
{
    assert(ht);

    return data % (ht->_capacity - 1);
}


//     
PNode BuyNode(DataType data)
{
    PNode pNewNode = NULL;
    pNewNode = (PNode)malloc(sizeof(Node));
    if (NULL == pNewNode)
        return NULL;

    pNewNode->_data = data;
    pNewNode->_pNext = NULL;

    return pNewNode;
}

//  
void     HashBucketPrint(HashBucket* ht)
{
    PNode pCur = NULL;
    assert(ht);

    for (int i = 0; i < ht->_capacity; ++i)
    {
        printf("Hash Bucket No.%ld:   ", i);
        pCur = ht->_table[i];
        while (pCur)
        {
            if ( ht->_setData == DataToInt)
            {
                printf("%d\t", pCur->_data);
            }
            else
            {
                printf("%s\t", pCur->_data);
            }
            pCur = pCur->_pNext;
        }
        putchar('
'); } } // size_t StrToInt(const char * str) { unsigned int seed = 131; // 31 131 1313 13131 131313 unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } // size_t DataToInt(int data) { return data; } void TestData() { HashBucket ht; HashBucketInit(&ht, 12, DataToInt); HashBucketInsertUnique(&ht, 1); HashBucketInsertUnique(&ht, 2); HashBucketInsertUnique(&ht, 5); HashBucketInsertUnique(&ht, 13); HashBucketInsertUnique(&ht, 24); HashBucketInsert(&ht, 2); HashBucketPrint(&ht); HashBucketDelete(& ht, 2); HashBucketPrint(&ht); //HashBucketDeleteUnique(&ht, 1); //HashBucketPrint(&ht); } #if 0 void TestStr() { HashBucket ht; HashBucketInit(&ht, 12, StrToInt); HashBucketInsertUnique(&ht, "lala"); HashBucketInsertUnique(&ht, "hah"); HashBucketInsertUnique(&ht, "pp"); HashBucketInsertUnique(&ht, "dsf"); HashBucketInsertUnique(&ht, "daf"); HashBucketInsert(&ht, "lala"); HashBucketPrint(&ht); HashBucketDelete(&ht, "lala"); HashBucketPrint(&ht); } #endif