多功能链表
来源:互联网 发布:张作霖 张学良 知乎 编辑:程序博客网 时间: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;}*/