• 实现极小一部分PHP的HASHMAP


    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <malloc.h>
    #include <math.h>
    typedef struct bucket{
        int h;  
        char* key;
        void* pData;
        struct bucket* pNext;
        struct bucket* pLast;
    }Bucket;
    typedef struct hashtable{
        int size;
        int elementsNum;
        int mask;
        Bucket** arBuckets; //这是一个存放buckets的array 
    }HashTable;
    
    /**
     **  这是一个计算HASH值的算法
     **/
    int time33(char* arKey,int arlength){
        int h = 0;
        int i;
        for(i=0;i<arlength;i++){
            h = h*33 + (int)*arKey++;
        }
        return h;    
    }
    
    /**
     **  初始化一个大小是1的HASHTABLE 
     **/
    int _init_hash_table(HashTable** ht){
        *ht = (HashTable*)malloc(sizeof(HashTable));
        (*ht)->size = 1;
        (*ht)->mask = (*ht)->size - 1;    
        (*ht)->elementsNum = 1;
        (*ht)->arBuckets = (Bucket**)malloc(sizeof(Bucket*)*(*ht)->size);
        memset((*ht)->arBuckets,0,sizeof(Bucket*)*(*ht)->size);
        return 1;        
    } 
    
    int _hash_link_bucket_to_bucket_head(Bucket** newBucket,Bucket** bucketHead){
        if(*bucketHead==NULL){
            *bucketHead = *newBucket;        
        }else{
            (*newBucket)->pNext = (*bucketHead)->pNext;
            (*newBucket)->pLast = (*bucketHead);
            if((*bucketHead)->pNext != NULL){
                (*bucketHead)->pNext->pLast = *newBucket;    
            }
            (*bucketHead)->pNext = *newBucket;    
        }
        return 1;
    }
    
    int _hash_new_bucket(Bucket** newBucket,int hash,char* arkey,void* pData){
        (*newBucket) = (Bucket*)malloc(sizeof(Bucket));
        (*newBucket)->h = hash;
        (*newBucket)->key = arkey;
        (*newBucket)->pData = pData;
        (*newBucket)->pNext = NULL;
        (*newBucket)->pLast = NULL;
        return 1;
    }
    
    
    int _hash_rehash(HashTable* ht){
        int i = 0;
        //由于我没定义pListNext指针,所以只能这样rehash了。 
        for( ; i<ht->size ; i++){
            if(ht->arBuckets[i] != NULL){
                int index = ht->arBuckets[i]->h & ht->mask ;
                if(i != index){
                    _hash_link_bucket_to_bucket_head(&ht->arBuckets[i],&ht->arBuckets[index]);
                    ht->arBuckets[i] = NULL;    
                }    
            }    
        }
        return 1;        
    }
    
    /**
     **  将HASHTABLE的大小扩容1倍 
     **/
    int _hash_resize(HashTable* ht){
        if(ht != NULL){
            ht->size = ht->size << 1;
            ht->mask = ht->size - 1; 
            realloc(&ht->arBuckets,sizeof(Bucket*) * ht->size);
            int i;
            for(i=ht->size>>1;i<ht->size;i++){
                ht->arBuckets[i] = NULL;
            }
            //memset(ht->arBuckets[0],NULL,sizeof(Bucket*) * (ht->size >> 1));
            printf("resize:%i\r\n", ht->size);
            _hash_rehash(ht);
            return 1;        
        }
        return 0;
    }
    
    
    /**
     **  往HASHTABLE中添加元素 
     **/
    int _hash_add_or_update(HashTable* ht,char* arKey,int arLength,void* pData){
        int h = time33(arKey,arLength);
        int index = h & ht->mask;
        Bucket* p = ht->arBuckets[index]; 
        while(p!=NULL){
            if(strcmp(arKey,p->key)==0){
                //这里应该执行更新操作
                free(p->pData);
                p->pData = pData; 
                return 1;
            }
            p = p->pNext;        
        }
        Bucket* newBucket;
        _hash_new_bucket(&newBucket,h,arKey,pData);
        _hash_link_bucket_to_bucket_head(&newBucket,&ht->arBuckets[index]);
        ht->elementsNum++;
        if(ht->elementsNum = ht->size){
            _hash_resize(ht);
        }
        return 0;
        
    }
    
    void* _hash_find(HashTable* ht,char* arKey,int arLength){
        int h = time33(arKey,arLength);
        int index = h & ht->mask;
        Bucket* p = ht->arBuckets[index]; 
        while(p!=NULL){
            if(strcmp(arKey,p->key)==0){
                return p->pData;
            }
            p = p->pNext;
        }
        return 0;
    }
    
    int PUT(HashTable* ht,void* key,void* value){
        char* arKey = (char*)key;
        int len = strlen(arKey);
        return _hash_add_or_update(ht,arKey,len,value);    
    }
    
    void* GET(HashTable* ht,void* key){
        char* arKey = (char*)key;
        int len = strlen(arKey);
        return _hash_find(ht,arKey,len);
    }
    
    int main(){
        printf("%s\r\n","这是一个hashtable的例子");
        HashTable* ht;
        _init_hash_table(&ht);
        PUT(ht,"1","mengjun");
        PUT(ht,"2","aaaaa");
        PUT(ht,"3","fff");
        PUT(ht,"24","eee");
        PUT(ht,"25","ddd");
        printf("%s\r\n",(char*)GET(ht,"1"));
        printf("%s\r\n",(char*)GET(ht,"2"));
        printf("%s\r\n",(char*)GET(ht,"3"));
        printf("%s\r\n",(char*)GET(ht,"24"));
        printf("%s\r\n",(char*)GET(ht,"25"));
        printf("HASHTABLE总共有元素%i个\r\n",ht->elementsNum);
        return 0;
    }
  • 相关阅读:
    一个简单的瀑布流效果
    C#遇到的一些奇怪问题
    能够按页号提取word文档文本内容的小程序,由C#实现
    设计模式学习之简单工场模式
    设计模式学习之策略模式
    检查机器是否安装了.NET Framework 或已经安装了哪些.net版本
    书籍清单
    使用Func<T>对对象进行排序
    定义一个委托的三种形式
    设计模式学习之设计原则
  • 原文地址:https://www.cnblogs.com/23lalala/p/2703691.html
Copyright © 2020-2023  润新知