基于链表法的Hash算法简易实现

来源:互联网 发布:数据库对接 接口调用 编辑:程序博客网 时间:2024/05/16 19:09

因项目需要,为了查找更快,通过输入pt,port两个数字,读取与之对应的Cos。Hash算法的精髓在于hash函数的设计,在此,我只简单地设计实现了一下。同时针对传入不同值得到相同的key,通过链表法解决:

#include "nl_common.h"       //自己项目里的.h文件typedef struct _node{    U8 pt;    U16 port;    U8 Cos;    struct _node *next;}node;void hash_insert(U8 pt, U16 port, U8 Cos);int find_key(U8 pt, U16 port);char fname[] = "/home/root/classifier";int node_num = 0;int mod_num;node * hashTab;int flag = 0;#define BigLittleSwap16(A)  ((((uint16)(A) & 0xff00) >> 8) | (((uint16)(A) & 0x00ff) << 8))int checkCPUendian(){       union{              unsigned long int i;              unsigned char s[4];       }c;       c.i = 0x12345678;       return (0x12 == c.s[0]);}unsigned short int HtoNs(unsigned short int h){       return checkCPUendian() ? h : BigLittleSwap16(h);}int file_len(){    FILE *fp_port = NULL;    char c;    int j = 0;    int len = 0;    fp_port = fopen(fname, "r");    if (NULL == fp_port)    {        EPT(stderr,"file: %s does't exist\n", fname);        return -1;    }    else    {        while((c = fgetc(fp_port)) != EOF)        {            j = (int)(c);            EPT(stderr,"@ j: '%d'\n",j);            if(j == 255)                break;            EPT(stderr,"! read : '%c'\n", c);            if(c == '\n')            {                len++;            }        }        node_num = len * 2;        EPT(stderr,"the size of file is %d\n", len);        if(len == 0)        {            EPT(stderr,"file: %s does't have word\n", fname);            return 0;        }        return 1;    }    fclose(fp_port);}void find_max_prime(){    int i;    int x = node_num;    while(x > 1)    {        for(i = 2; i < x; i++)        {            if(x % i == 0)            {                x --;                break;            }        }        if( i == x)            break;    }    mod_num = x;    EPT(stderr,"mode_num: %d\n", mod_num);}int read_file(){    int rval = 0;    FILE *fp_port = NULL;    fp_port = fopen(fname, "r");    if (NULL == fp_port)    {        rval = 1;        goto fexit;    //  printf("~~~~~~does not exist file:%s\n",fname);    }    else    {        while(!feof(fp_port))        {            int pt;            int port;            int Cos;            fscanf(fp_port, "%d %d %d", &pt, &port, &Cos);            EPT(stderr,"%d %d %d (%hhu %hu %hhu)\n", pt, port, Cos, pt, port, Cos);            if(!feof(fp_port))        //  printf("%d, %d, %d\n", pt, port, Cos);            {                hash_insert((U8)pt, (U16)HtoNs(port), (U8)Cos);            }            rval = 2;        }    }fexit:    if (NULL != fp_port)        fclose(fp_port);    return rval;}void hash_insert(U8 pt, U16 port, U8 Cos){    int key;    key = find_key(pt, port);    if(hashTab[key].Cos == 255)    {        EPT(stderr,"key:%d\n", key);        hashTab[key].pt = pt;        hashTab[key].port = port;        hashTab[key].Cos = Cos;    }    else    {        node *temp;        node *new_node = (node *)calloc(1, sizeof(node));        new_node->pt = pt;        new_node->port = port;        new_node->Cos = Cos;        new_node->next = NULL;        temp = &hashTab[key];        for(; temp->next != NULL; temp = temp->next)            printf("   ");        EPT(stderr,"key:%d\n", key);        temp->next = new_node;    }}int find_key(U8 pt, U16 port){    int key;    key = ( pt + (pt<<5) + port ) % mod_num;    return key;}void init_hash(){    int i;    for( i = 0; i < node_num; i++)    {        hashTab[i].pt = 0;        hashTab[i].port = 0;        hashTab[i].Cos = -1;        hashTab[i].next = NULL;    }}void show_hash(){    int i;    for(i = 0; i < node_num; i++)    {        int num = 1,j;        char str[] = "   ";        EPT(stderr,"hashTab[%d] -> pt: %hhu, port: %hu, Cos: %hhu\n", i,             hashTab[i].pt, hashTab[i].port, hashTab[i].Cos);        node * temp = &hashTab[i];        while(temp->next != NULL)        {            temp = temp->next;            for(j = num ; j > 0; j--)            {                printf("%s", str);            }            num++;            EPT(stderr,"next -> pt: %hhu, port: %hu, Cos: %hhu\n",             temp->pt, temp->port, temp->Cos);        }    }}U8 find_Cos(U8 pt, U16 port){    int key;    key = find_key(pt, port);    EPT(stderr, "~ find key: %d(%hhu)(pt: %hhu ,port: %hu)\n", key, key, pt, port);    if(flag)        return -1;    if(hashTab[key].Cos == 255)    {        return -1;    }    else    {        node *temp;        temp = &hashTab[key];        do        {            if( (temp->pt == pt) && (temp->port == port) )                return (temp->Cos);            temp = temp->next;        }        while(temp != NULL);    }}int init_nl_hash(){    int rval;    if( file_len() == 1)    {        find_max_prime();           hashTab = (node*)calloc(node_num, sizeof(node));        init_hash();        show_hash();        read_file();        show_hash();          return 1;       }    flag = 1;    return 0;}/*//for testvoid main(){    int i;    file_len();    find_max_prime();       hashTab = (node*)calloc(node_num, sizeof(node));    init_hash();    show_hash();    read_file();    show_hash();    int pt_temp, port_temp;    for(i = 0; i < 5; i++)    {        fscanf(stdin, "%d %d", &pt_temp, &port_temp);        printf("pt:%d, port:%d, Cos:%d\n", pt_temp,port_temp,find_Cos(pt_temp,HtoNs(port_temp)));    }    free(hashTab);  //这里只free(hashTab)肯定不行,还需要把next指针非NULL的也释放掉                    //因为测试时候需要,项目中不需要了,就没完善。}*/

其中有一点需要注意:
在 file_len() 函数中,加入了:

            j = (int)(c);            EPT(stderr,"@ j: '%d'\n",j);            if(j == 255)                break;

本来在电脑上模拟测试时候,通过EOF标识符可以判断文件结束,但是到板子上,通过ps命令发现该进程一直在执行,通过打印语句才发现原来while()语句一直在读,读出的数为255,

EOF 定义的为-1,转换为int为255,所以读出的为255可以解释。

但是为何通过EOF编制为来判断getchar()不行还未想通。。。

0 0
原创粉丝点击