多功能链表

来源:互联网 发布:张作霖 张学良 知乎 编辑:程序博客网 时间:2024/04/30 02:12
//此链表具有StringBuffer, HashTab, List, Vector 的功能#ifndef _list_#define _list_#include "stdbool.h"struct item{    char        * data;    unsigned int  size;    unsigned int  hash;    struct item * last;    struct item * next;};struct list{    struct item * head;    struct item * end;    unsigned int  items; //子节点个数    unsigned int  length;};#define PUSH_FL_EMPTY 0#define PUSH_FL_DATA  1#define PUSH_FL_HASH  2#define PUSH_FL_ALL   PUSH_FL_DATA|PUSH_FL_HASH#define init_list(plist) memset(plist,0,sizeof(struct list))void  push_list(struct list *plist, void *pdata, unsigned int size, unsigned int flag); //将p指向的size个字节数据存入链表void  clear_list(struct list *plist);    //清除链表void  pop_list(struct list *plist);      //弹出最后一个节点数据void *compress_list(struct list *plist); //将链表压缩为数据流#endif //(_list_)
#include <stdlib.h>#include <stdio.h>#include "list.h"// BKDR Hash Functionunsigned int BKDRHash(char *str, unsigned int len){    unsigned int seed = 131; // 31 131 1313 13131 131313 etc..    unsigned int hash = 0;    unsigned int i;    if (len)    {        for(i=0;i<len;i++)        {            hash = hash * seed + (str[i]);        }    }else{        while (*str)        {            hash = hash * seed + (*str++);        }    }    return (hash & 0x7FFFFFFF);}void push_list(struct list *plist, void *pdata, unsigned int size, unsigned int flag){    struct item *pitem;    if (pdata==0 || size==0) return ;        pitem=(struct item *)malloc(sizeof(struct item)+((flag&PUSH_FL_DATA)?size+1:0));    if (pitem)    {        if (flag&PUSH_FL_DATA)        {            pitem->size=size;            pitem->data=(char *)pitem+sizeof(struct item);            memcpy(pitem->data,pdata,size);            pitem->data[size]=0;        }else{            pitem->size=0;            pitem->data=0;        }                if (flag&PUSH_FL_HASH)        {            pitem->hash=BKDRHash((const char *)pdata,size);                }else{            pitem->hash=0;        }        pitem->next=0;        pitem->last=0;        if (plist->head==0)        {            plist->end=plist->head=pitem;        }else if (plist->end){            pitem->last=plist->end;            plist->end->next=pitem;        }        plist->end=pitem;        plist->length+=pitem->size;        plist->items++;    }}//从链表里寻找int find_item(struct list *plist, void *pdata, unsigned int size){    if (pdata==0 || size==0) return -1;    int i;    unsigned int hash;    struct item *pitem;    struct item *next;    pitem=plist->head;    hash=BKDRHash((const char *)pdata,size); //计算要查找数据的hash值    i=0;    while(pitem)    {        //如果hash值非0,则使用hash值匹配        if (pitem->hash)        {            if (pitem->hash==hash)    return i;        //负责逐字节匹配        }else if (strncmp((const char *)pitem->data,(const char *)pdata,size)==0){            return i;        }        pitem=pitem->next; i++;    }    return -1;}void clear_list(struct list *plist){    struct item *pitem;    struct item *next;    pitem=plist->head;    while(pitem)    {        //保存下一个节点指针        next=pitem->next;        //释放当前节点内存        free(pitem);        pitem=next;    }    plist->end=plist->head=0;}void pop_list(struct list *plist){}void * compress_list(struct list *plist){    struct item *pnew;    struct item *pitem;    struct item *next;    char        *pdata;    pnew=(struct item *)malloc(sizeof(struct item)+plist->length+1);    if (pnew)    {        pnew->size=plist->length;        pnew->data=(char *)pnew+sizeof(struct item);        pnew->next=0;        pitem=plist->head;        pdata=(char *)pnew->data;        while(pitem)        {            //保存下一个节点指针            next=pitem->next;            if (pitem->size)            {                //复制节点数据                memcpy(pdata,pitem->data,pitem->size);                pdata+=pitem->size;            }            //释放当前节点内存            free(pitem);                pitem=next;        }        *pdata=0;        plist->head=pnew;        return pnew->data;    }    return 0;}//#include <time.h>/*int main(int argc, char **argv){    unsigned int i,j;    struct list l;    init_list(&l);    char temp[10];    srand(time(0));    for (i=0;i<10000;i++)    {        for(j=0;j<10;j++)        {            temp[j]=rand()%256;        }        if (find_item(&l,temp,10)==-1)        {            push_list(&l,temp,10,PUSH_FL_HASH);        }    }    printf("items:%d length:%d\n", l.items, l.length);    clear_list(&l);    return 0;}*/
原创粉丝点击