开散列、闭散列实现及性能比较

来源:互联网 发布:python 求平均值 编辑:程序博客网 时间:2024/06/07 15:17

总程序实现了添加数据信息,建立开散列表,闭散列表,开散列和闭散列的查找,时间性能分析,还有溢出表的建立与查找这些功能。

下面分开说明原理:

开散列表:运用单链表存储方式,不产生堆积现象,但因为附加了指针域而增加了空间开销。

闭散列表:运用顺序表存储,存储效率较高,但容易产生堆积,查找不易实现,需要用到二次再查找。

溢出表:开、闭散列的结合运用,第一个顺序表存放类似指针域,第二个则存放溢出。




实现:

#include<iostream>#include<cstdio>#include<stdio.h>#include<stdlib.h>#define HashSize 53#define MaxSize 20using namespace std;typedef struct{    int key;    int si;} HashTable1;void CreateHashTable1(HashTable1 *H,int *a,int num)//哈希表线性探测在散列;{    int i,d,cnt;    for(i=0; i<HashSize; i++)    {        H[i].key=0;        H[i].si=0;    }    for(i=0; i<num; i++)    {        cnt=1;        d=a[i]%HashSize;        if(H[d].key==0)        {            H[d].key=a[i];            H[d].si=cnt;        }        else        {            do            {                d=(d+1)%HashSize;                cnt++;            }            while(H[d].key!=0);            H[d].key=a[i];            H[d].si=cnt;        }    }    printf("\n线性再探索哈希表已建成!\n");}void SearchHash1(HashTable1 *h,int data){    int d;    d=data%HashSize;    if(h[d].key==data)        printf("数字%d的探查次数为:%d\n",h[d].key,h[d].si);    else    {        do            d=(d+1)%HashSize;        while(h[d].key!=data && d<HashSize);        if(d<HashSize)            printf("数字%d的探查次数为:%d\n",h[d].key,h[d].si);        else            printf("没有查找到你所输入的数\n");    }}typedef struct node{    int key;    int si;    struct node *next;}Node;typedef struct{    Node *link;}HashTable2;void CreateHashTable2(HashTable2 *ht[],int *a,int num)//哈希表链地址;{    int i,d,cnt;    Node *s,*q;    for(i=0; i<num; i++)    {        ht[i]=(HashTable2 *)malloc(sizeof(HashTable2));        ht[i]->link=NULL;    }    for(i=0; i<num; i++)    {        cnt=1;        s=(Node *)malloc(sizeof(Node));        s->key=a[i];        s->next=NULL;        d=a[i]%num;        if(ht[d]->link==NULL)        {            ht[d]->link=s;            s->si=cnt;        }        else        {            q=ht[d]->link;            while(q->next!=NULL)            {                q=q->next;                cnt++;            }            cnt++;            s->si=cnt;            q->next=s;        }    }}void SearchHash2(HashTable2 * h[],int data,int num){    int d;    Node *q;    d=data%num;    q=h[d]->link;    while(q->key!=data && q->next!=NULL)        q=q->next;    if(q->next!=NULL)        printf("数字%d的查找次数为:%d\n",q->key,q->next);    else        printf("没有找到你要查找的那个数\n");}typedef struct{    int * elem[HashSize];    int count;    int size;} HashTable3;int Collision(int p,int &c)//二次探测再散列法解决冲突{    int i,q;    i=c/2+1;    while(i<HashSize)    {        if(c%2==0)        {            c++;            q=(p+i*i)%HashSize;            if(q>=0)                return q;            else                i=c/2+1;        }        else        {            q=(p-i*i)%HashSize;            c++;            if(q>=0)return q;            else i=c/2+1;        }    }    return (-1);}void CreateHash3(HashTable3 *h,int *a,int num)//二次探索表{    int i,p=-1,c,pp;    for(i=0; i<num; i++)    {        c=0;        p=a[i]%HashSize;        pp=p;        while(h->elem[pp]!=NULL)        {            pp=Collision(p,c);            if(pp<0)            {                printf("第%d个记录无法解决冲突\n",i+1);                continue;            }        }        h->elem[pp]=&(a[a[i]]);        h->count++;        printf("第%d个记录冲突次数为%d\n",i+1,c);    }    printf("\n建表完成!\n此哈希表容量为%d,当前表内存储的记录个数%d.\n",HashSize,h->count);}void SearchHash3(HashTable3 *h,int data)//哈希表二次探索再散列查找{    int c=0,p,pp;    p=data%HashSize;    pp=p;    while((h->elem[pp]!=NULL)&&(*(h->elem[pp])!=data))        pp=Collision(p,c);    if((h->elem[pp]!=NULL)&&(*(h->elem[pp])==data))        printf("\n查找成功!\n查找冲突次数为%d:",c);    else        printf("\n没有查到此数!\n");}int num;void GetIn(int *a){    printf("输入添加的个数:");    scanf("%d",&num);    for(int i=0; i<num; i++)        scanf("%d",&a[i]);    printf("数据已经输入完毕!\n");}void GetOut(int *a){    printf("你所输入的数据:");    for(int i=0; i<num; i++)        printf("%d,",a[i]);    printf("\n输出已完毕!");}void menu(){    printf("             散列法的实验研究");    printf("\n 【1】. 添加数据信息       【2】 数据的输出");    printf("\n 【3】. 建立哈希表(线性再散列) ");    printf("\n 【4】. 建立哈希表(二次探测再散列)");    printf("\n 【5】. 建立哈希表(链地址法)");    printf("\n 【6】. 线性再散列法查找");    printf("\n 【7】. 二次探测再散列法查找");    printf("\n 【8】. 链地址法查找");    printf("\n 【0】. 退出程序");    printf("\n");}int main(){    int data;    HashTable1 hash1[HashSize];    HashTable2 * hash2[HashSize];    HashTable3 * ha;    ha=(HashTable3 *)malloc(sizeof(HashTable3));    for(int i=0; i<HashSize; i++)        ha->elem[i]=NULL;    ha->count=0;    ha->size=HashSize;    int a[MaxSize];    menu();    while(1)    {        printf("请输入一个任务选项>>>");        int x;        scanf("%d",&x);        switch(x)        {        case 1:            GetIn (a);            break;        case 2:            GetOut(a);            break;        case 3:            CreateHashTable1(hash1,a,num);            break;        case 4:            CreateHash3(ha,a,num);            break;        case 5:            CreateHashTable2(hash2,a,num);            break;        case 6:            printf("请输入你查找的数据:");            scanf("%d",&data);            SearchHash1(hash1,data);            break;        case 7:            printf("请输入你查找的数据:");            scanf("%d",&data);            SearchHash3(ha,data);            break;        case 8:            printf("请输入你查找的数据:");            scanf("%d",&data);            SearchHash2(hash2,data,num);            break;        case 0:            exit(-1);        }    }    return 0;}溢出表:#include <iostream>#include<ctime>#define B 10#define empty 0#define test 100000#define max 10000typedef int keytype;using namespace std;struct records{keytype key;};struct celltype{records data;celltype *next;};typedef celltype *cellptr;typedef struct nod{celltype *next;}*node;typedef node HASH[B];HASH F;int h(keytype k){return k%B;}cellptr Search(keytype k){cellptr bptr;bptr=F[h(k)]->next;while(bptr!=NULL)if(bptr->data.key==k)return bptr;elsebptr=bptr->next;return bptr;}void Delete(keytype k){int bucket=h(k);cellptr bptr,p;if(F[bucket] != NULL)//可能在表中if(F[bucket]->next->data.key==k){//首元素就是bptr=new celltype;bptr=F[bucket]->next;F[bucket]->next=F[bucket]->next->next;delete(bptr);}else{//可能在中间或不存在bptr=F[bucket]->next;while(bptr->next!=NULL)if(bptr->next->data.key==k){p=bptr->next;bptr->next=p->next;delete( p);}elsebptr=bptr->next;}}void Insert(keytype k){int bucket;cellptr oldheader;{bucket=h(k);oldheader=F[bucket]->next;F[bucket]->next=new celltype;F[bucket]->next->data.key=k;F[bucket]->next->next=oldheader;}}int main(){long start,end,t1,t2,t3;start=clock();    for (int i=0;i<=B;i++)    {F[i]=new nod;F[i]->next=NULL;    }for(int i=0;i<test;i++)Insert(i);    end=clock();    t1=end-start;    cout<<"插入完成"<<endl;    cout<<"插入用时:"<<t1<<"毫秒"<<endl;    start=clock();    for(int i=0;i<test;i++)        Search(i);    end=clock();    t2=end-start;    cout<<"查找完成"<<endl;    cout<<"查找用时:"<<t2<<"毫秒"<<endl;    start=clock();    for(int i=0;i<test;i++)        Delete(i);    end=clock();    t3=end-start;    cout<<"删除完成"<<endl;    cout<<"删除用时:"<<t3<<"毫秒"<<endl;    cout<<"全部计算完成"<<endl;    return 0;}



0 0
原创粉丝点击