首页 > 技术文章 > c_数据结构_哈希表

Vera-y 2019-09-09 15:10 原文

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 0
#define OK 1
#define Size 21   // 指定质数(数组长度)
typedef struct{
    char name[20];
    char address[20];
    char num[12];
}mul;
typedef struct{ 
    mul data[20]; 
    int size;
}Hashtable;
void init(Hashtable &h)
{
    for(int i=0;i<Size;i++){
            h.data[i].num[0]=0;//首位赋为0    
    }
    h.size = Size;
}
// 判断电话簿是否为空
int kong(Hashtable &h){
    for(int i=0;i<Size;i++){
        if(h.data[i].num[0]!=0){
            return ERROR;
        }
    }
    return OK;
}
int HashSearch(Hashtable &h);

// 新存入的数的和是否已经被存储了
int c_t(Hashtable &h,int sum){
    int m,n,sum1=0;
    for(int k=0;k<Size;k++){               //循环整个数组
        n = strlen(h.data[k].num);
        if(h.data[k].num[0]!=0){
            for(m=0;m<n;m++){
                sum1=sum1+h.data[k].num[m]-'0';   
            }
            if(sum1==sum){
                printf("您输入的电话号码已经被存储,请重新输入\n\n");
                HashSearch(h);
                fflush(stdin);
                return ERROR;
            }
        }
    }
    return OK;
}
// 寻址存数
int HashSearch(Hashtable &h) 
{
    char  nu[12],na[20],add[50];
    int i,p,j,y=0,boo=1;//nu关键字
    int m,n,sum=0,sum1=0; 
    printf("请输入要存入的电话记录的姓名、地址和11位手机号码(用空格隔开)\n");
    scanf("%s",na);
    scanf("%s",add);
    scanf("%s",nu);
    n=strlen(nu);  // 电话号的长度
    if(n==11){
        for(m=0;m<n;m++){
            sum=sum+nu[m]-'0';   // 计算电话号码的总和进行存储
            }
        boo=c_t(h,sum);    // 判断输入的数是否被存储了
        if(boo){
        j=sum%Size;//哈希函数
        if(h.data[j].num[0]==0){                                                                                                          
            p=j;
            h.size=j;
        }else{
            i=(j+1)%Size;     // 向后探测一个位置
            if(h.data[i].num[0]==0){
                    p=i;
                    h.size=i;
                }
            while(h.data[i].num[0]!=0 && i!=j) {            
                i=(i+1)%Size;    //向后探测位置
                if(h.data[i].num[0]==0){
                    p=i;
                    h.size=i;
                    break;
                }
            }
            if (i==j){
                printf("当前电话谱最多只能实现 %d 个数据存储\n",Size);
                return ERROR;
            }
        }
        strcpy(h.data[p].num,nu);   // 把存入的数据放入定义的数组指定位置
        strcpy(h.data[p].address,add);
        strcpy(h.data[p].name,na);
        printf("存入数据 %d 号位置: %s    %s   %s\n",h.size,h.data[p].name,h.data[p].address,h.data[p].num);
        }
    }else{
        printf("\n!!!请输入11位手机号码!!!\n");
        HashSearch(h);
    }
    return OK;
}
// 批量存入电话记录
int pl_HashSearch(Hashtable &h){
    int n=0;
    printf("请输入您要添加电话记录的条数:");
    scanf("%d",&n);
    if(1<n&&n<21){
        for(int i=0;i<n;i++){
            HashSearch(h);
        }
    }else{
        printf("\n您存入的条数大于20条 或者小于2条\n\n");
        pl_HashSearch(h);        
    }
    return OK;
}
// 打印所有记录
void disp(Hashtable &h)
{
    printf("电话簿中电话记录如下:\n");
    for(int i=0;i<Size;++i){
        if(h.data[i].num[0]){
            printf("%d号位置\n姓名:%s  地址:%s 电话:%s\n",i,h.data[i].name,h.data[i].address,h.data[i].num);
        }
    }
}
// 哈希查找
int hash_kind(Hashtable h){
    char num[12];
    int i,j,y=0;//nu关键字
    int m,n,sum=0; 
    printf("请输入您要在电话簿中查找的电话号码:\n");
    scanf("%s",&num);
    n=strlen(num);  // 电话号的长度
    for(m=0;m<n;m++){
        sum=sum+num[m]-'0';   // 计算电话号码的总和进行存储
        }
    j=sum%Size;//哈希函数
    if(strcmp(h.data[j].num,num)==0){   // 探测查找
        printf("您要查找的相关信息:%d号位置: \n姓名:%s\n地址:%s\n电话号码:%s\n",j,h.data[j].name,h.data[j].address,h.data[j].num);
    }
    else{
        i=(j+1)%Size;             
        while(h.data[i].num[0]!=0 && i!=j) {  
            if(strcmp(h.data[i].num,num)==0){   
                printf("您要查找的相关信息:%d号位置 : \n姓名:%s\n地址:%s\n电话号码:%s\n",i,h.data[j].name,h.data[j].address,h.data[j].num);
                break;
            }
            i=(i+1)%Size;    //向后探测一个位置
        }
        if(h.data[i].num[0]==0){
            printf("\n(嘟。。)当前号码谱没有此号码!!查无此人!!查无此人!!\n");
            return ERROR;
        }
        
    }    
    return OK;    
}
 //操作菜单
void OperateMenu(){      

    printf("\n\n--------------请选择元素处理方式---------\n\n");
    printf("注:电话号应为 11 位\n\n");
    printf("0> :退出\n\n");
    printf("1>: 存入电话号\n\n");
    printf("2>: 批量存入电话号\n\n");
    printf("3>: 哈希查找电话号\n\n");
    printf("4>: 显示电话簿\n\n");
    printf("请选择对元素的处理:");
}
void main(){
    int w=0,k,boo=1,i=1,e=0;
    Hashtable h;
    printf("注:此测试过程输入值应全为数字\n\n");
    printf("进入号码簿存储请输入:'1'\n\n");
    printf("退出请选择'0'或 其它!!\n\n");
    printf("请选择:");
    scanf("%d",&w);
    if(w==1){
        init(h);
        OperateMenu();
        scanf("%d",&k);
        while(k){
            switch(k){
                case 0:break;
                case 1:boo=HashSearch(h);
                    if(boo)
                        printf("存入成功!!\n");
                    else
                        printf("存入失败!!\n");
                    break;
                case 2:boo=pl_HashSearch(h);
                    if(boo)
                        printf("批量存入成功!!\n");
                    else
                        printf("批量存入失败!!\n");
                    break;
                case 3:boo=kong(h);
                    if(boo==1){
                        printf("\n!!当前电话簿为空!!\n");
                    }else{
                        boo=hash_kind(h);
                        if(boo)
                            printf("哈希查找成功!!\n");
                        else
                            printf("哈希查找失败!!\n");
                        }
                    break;

                case 4:
                    boo=kong(h);
                    if(boo==1){
                        printf("\n!!当前电话簿为空!!\n");
                    }else{disp(h);    }break;
            }
            OperateMenu();
            scanf("%d",&k);
        }
    }
}

 

推荐阅读