#include<stdio.h>
#include<malloc.h>

#define NULLKEY 0
#define N 10

typedef int KeyType;

typedef struct
{
    KeyType key;
    int ord;
}ElemType;

int hashsize[]={11,19,29,37};
int m=0;

typedef struct
{
    ElemType *elem;
    int count;
    int sizeindex;
}HashTable;

#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1

int InitHashTable(HashTable *H)
{
    int i;
    (*H).count=0;
    (*H).sizeindex=0;
    m=hashsize[0];
    (*H).elem=(ElemType*)malloc(m*sizeof(ElemType));
    if(!(*H).elem)
        exit(0);
    for(i=0;i<m;i++)
        (*H).elem[i].key=NULLKEY;
    return 1;
}

void DestroyHashTable(HashTable *H)
{
    free((*H).elem);
    (*H).elem=NULL;
    (*H).count=0;
    (*H).sizeindex=0;
   
}

unsigned Hash(KeyType K)
{
    return K%m;
}

void collision(int *p,int d)
{
    *p=(*p+d)%m;
}

int SearchHash(HashTable H,KeyType K,int *p,int *c)
{
    *p=Hash(K);
    while(H.elem[*p].key!=NULLKEY&&!(K == H.elem[*p].key))
    {
        (*c)++;
        if(*c<m)
            collision(p,*c);
        else
            break;
    }
    if (K == H.elem[*p].key)
        return SUCCESS;
    else
        return UNSUCCESS;
}

int InsertHash(HashTable *,ElemType);

void RecreateHashTable(HashTable *H)
{
    int i,count=(*H).count;
    ElemType *p,*elem=(ElemType*)malloc(count*sizeof(ElemType));
    p=elem;
    printf("recreate the hashtable\n");
    for(i=0;i<m;i++)
        if(((*H).elem+i)->key!=NULLKEY)
            *p++=*((*H).elem+i);
    (*H).count=0;
    (*H).sizeindex++;
    m=hashsize[(*H).sizeindex];
    p=(ElemType*)realloc((*H).elem,m*sizeof(ElemType));
    if(!p)
        exit(0);
    (*H).elem=p;
    for(i=0;i<m;i++)
        (*H).elem[i].key=NULLKEY;
    for(p=elem;p<elem+count;p++)
        InsertHash(H,*p);
}
int InsertHash(HashTable *H,ElemType e)
{
    int c,p;
    c=0;
    if(SearchHash(*H,e.key,&p,&c))
        return DUPLICATE;
    else if(c<hashsize[(*H).sizeindex]/2)
    {
        (*H).elem[p]=e;
        ++(*H).count;
        return 1;
    }
    else
        RecreateHashTable(H);
    return 0;
}

void TraverseHash(HashTable H,void(*Vi)(int,ElemType))

    int i;
    printf("hash address:0~%d\n",m-1);
    for(i=0;i<m;i++)
        if(H.elem[i].key!=NULLKEY)
            Vi(i,H.elem[i]);
}

int Find(HashTable H,KeyType K,int *p)
{
    int c=0;
    *p=Hash(K);
    while(H.elem[*p].key!=NULLKEY&&!(K == H.elem[*p].key))
    {
        if(c<m)
            collision(p,c);
        else
            return UNSUCCESS;
    }
    if (K == H.elem[*p].key)
        return SUCCESS;
    else
        return UNSUCCESS;
}

void print(int p,ElemType r)
{
    printf("address=%d (%d,%d)\n",p,r.key,r.ord);
}

int main()
{
    ElemType r[N] = {
        {17,1},{60,2},{29,3},{38,4},{1,5},
        {2,6},{3,7},{4,8},{60,9},{13,10}
    };
    HashTable h;
    int i, j, p;
    KeyType k;
   
    InitHashTable(&h);
    for(i=0;i<N-1;i++)
    {
        j=InsertHash(&h,r[i]);
        if(j==DUPLICATE)
            printf("There has record %d,you cannot insert number(%d,%d)\n",r[i].key,r[i].key,r[i].ord);
    }
    printf("acorrd to the order of address ,the Hash tableis: \n");
    TraverseHash(h,print);
    printf("search number:");
    scanf("%d",&k);
    j=Find(h,k,&p);
    if(j==SUCCESS)
        print(p,h.elem[p]);
    else
        printf("cannot find\n");
    j=InsertHash(&h,r[i]);
    if(j==0)
        j=InsertHash(&h,r[i]);
    printf("the hashtable of the address order is:\n");
    TraverseHash(h,print);
    printf("search number:");
    scanf("%d",&k);
    j=Find(h,k,&p);
    if(j==SUCCESS)
        print(p,h.elem[p]);
    else
        printf("cannot find\n");
    DestroyHashTable(&h);
   
//    system("pause");
    return 0;
}

posted on 2011-06-30 15:44  hotty  阅读(679)  评论(0)    收藏  举报