用链地址法解决冲突的哈希表

/*
作者:徐**
日期:12.29  918
Version:v1.0
作用:简单员工管理系统
 每个员工的信息包括:编号,姓名, 性别,出生年月日,
 学历,职务,电话,住址等。系统的功能包括:
  1,查询:按特定条件查找员工
  2,修改:按编号对某个员工的某项信息进行修改
  3,插入:加入新员工的信息
  4,删除:按编号删除已离职的员工的信息
  5,排序:按特定条件对所有的员工的信息进行排序
*/
#include <iostream>
using namespace std;
#include <stdio.h>
#include <string.h>

#define HASHKEY 13
#define NULLKEY -1
#define MAX 20

typedef struct employee
{
    int key_code;
    char name[30];
    char sex;
    char borndate[30];
    char education[10];
    char position[15];
    char phone[15];
    char addr[30];
    struct employee *next;
}Employee;
              
typedef struct hashtable        //用链地址法解决冲突问题
{
    int key;
    struct employee *next;
}HashTable[MAX];

/function/
int Hash(int key)                 //哈希函数
{
    int mode = key % HASHKEY;
    return mode;
}
void Hash_Init(HashTable ht)          //哈希表初始化
{
    int i;
    for(i = 0; i < MAX; i++)
    {
        ht[i].key = NULLKEY;
        ht[i].next = NULL;
    }
}
int Hash_Insert(HashTable ht, Employee *em)
{
    int key = Hash(em->key_code);
    Employee *p;
    if(ht[key].key == NULLKEY)
    {
        ht[key].key = key;
        ht[key].next = em;
    }
    else if(ht[key].key == key)        //发生冲突,则用链地址发解决冲突
    {
        p = ht[key].next;
        while(p->next != NULL)            //寻找插入位置,插到表同义词最末尾
        {
            p = p->next;
        }
        p->next = em;
    }
    return 1;
}
Employee* Hash_Search(HashTable ht, int key)
{
    int p0 = Hash(key);
    if(ht[p0].key == NULLKEY) return NULL;
    else if(ht[p0].key == p0)        //如果找到一组同一词,则在同义词中查找
    {
        Employee *p = ht[p0].next;
        while(p != NULL)
        {
            if(p->key_code == key)
            {
                return p;
            }
            p = p->next;
        }
    }
    return NULL;
}

void Modify(Employee *em)
{
    int choice = 0;
    cout<<"What to Modify ======"<<endl;
    cout<<"1.position"<<endl;
    cout<<"2.phone"<<endl;
    cout<<"3.addr"<<endl;
    cout<<endl<<"Option -- ";
    cin>>choice;

    switch(choice)
    {
    case 1:
        char position[10];
        memset(position, 0x00, sizeof(position));
        cout<<"Change to : ";
        cin>>position;
        strcpy(em->position, position);
        cout<<"OK!"<<endl;
        break;
    case 2:
        char phone[15];
        memset(phone, 0x00, sizeof(phone));
        cout<<"Change to : ";
        cin>>phone;
        strcpy(em->phone, phone);
        cout<<"OK!"<<endl;
        break;
    case 3:
        char addr[30];
        memset(addr, 0x00, sizeof(addr));
        cout<<"Change to : ";
        cin>>addr;
        strcpy(em->addr, addr);
        cout<<"OK!"<<endl;
        break;
    default:
        cout<<"您选错了,请看清选项数字~"<<endl;
    }
}
int Hash_Modify(HashTable ht, int key)
{
    int p0 = Hash(key);
    if(ht[p0].key == NULLKEY) return NULLKEY;
    else if(ht[p0].key == p0)
    {
        Employee *p = ht[p0].next;
        while(p != NULL)
        {
            if(p->key_code == key)
            {   
                Modify(p);
                return p0;
            }
            p = p->next;
        }
    }
    return NULLKEY;
}
int Hash_Delete(HashTable ht, int key)
{
    int p0 = Hash(key);
    if(ht[p0].key == NULLKEY) return NULLKEY;
    else if(ht[p0].key == p0)
    {
        Employee *p = ht[p0].next, *pre = p;
        while(p != NULL)
        {
            if(p->key_code == key)
            {   
                if(p == ht[p0].next)
                {
                    ht[p0].next = p->next;
                }
                else
                {
                    pre->next = p->next;
                }
                free(p);
                return p0;
            }
            pre = p;
            p = p->next;
        }
    }
    return NULLKEY;
}
void Swap(Employee *em1, Employee *em2)
{
    Employee em_temp;
    em_temp.key_code = em1->key_code;
    em1->key_code = em2->key_code;
    em2->key_code = em_temp.key_code;
    strcpy(em_temp.addr, em1->addr);
    strcpy(em1->addr, em2->addr);
    strcpy(em2->addr, em_temp.addr);
    strcpy(em_temp.borndate, em1->borndate);
    strcpy(em1->borndate, em2->borndate);
    strcpy(em2->borndate, em_temp.borndate);
    strcpy(em_temp.education, em1->education);
    strcpy(em1->education, em2->education);
    strcpy(em2->education, em_temp.education);
    strcpy(em_temp.name, em1->name);
    strcpy(em1->name, em2->name);
    strcpy(em2->name, em_temp.name);
    strcpy(em_temp.phone, em1->phone);
    strcpy(em1->phone, em2->phone);
    strcpy(em2->phone, em_temp.phone);
    strcpy(em_temp.position, em1->position);
    strcpy(em1->position, em2->position);
    strcpy(em2->position, em_temp.position);
    em_temp.sex = em1->sex;
    em1->sex = em2->sex;
    em2->sex = em_temp.sex;
}
int Hash_Sort(HashTable ht)
{
    int k;
    for(k = 0; k < MAX; k++)
    {
        if(ht[k].key == NULLKEY)
            continue;
        else
        {
            Employee *p = ht[k].next, *q = p->next;
            while(p != NULL)
            {
                while(q != NULL)
                {
                    if(p->key_code > q->key_code)
                    {
                        Swap(p, q);
                    }
                    q = q->next;
                }
                p = p->next;
            }
        }
    }
    return 1;
}
Employee *Record_Input()
{
    Employee *em = (Employee *)malloc(sizeof(Employee));
    cout<<"/t请输入此员工的编号 : ";
    cin>>em->key_code;
    cout<<"/t请输入此员工的姓名 : ";
    cin>>em->name;
    cout<<"/t请输入性别(N or F) : ";
    cin>>em->sex;
    cout<<"/t请输入出生年月日 : ";
    cin>>em->borndate;
    cout<<"/t请输入教育程度 : ";
    cin>>em->education;
    cout<<"/t请输入职位 : ";
    cin>>em->position;
    cout<<"/t请输入电话号码 : ";
    cin>>em->phone;
    cout<<"/t请输入居住地址 : ";
    cin>>em->addr;
    em->next = NULL;
   
    return em;
}

int Hash_Create(HashTable ht)
{
    int count = 1;
    Employee *em;
    Hash_Init(ht);
//    for(count = 0; count < 3; count++)    //先创建3个员工的记录
    cout<<"/t==============创建员工信息表================"<<endl;
    while(count != 0)
    {
        em = Record_Input();
       
        if(Hash_Search(ht, em->key_code) == NULL)
            Hash_Insert(ht, em);
        else
        {
            count--;
            cout<<"编号不能重复~ -_-"<<endl;
            cout<<"是否c重新输入? 1 或 0 , choose : ";
            cin>>count;
            if(count != 0)
                continue;
            else
                break;
        }
        cout<<"是否再次输入一个员工? 1 或 0 , choose : ";
        cin>>count;
    }

    printf("/nCreate Successfully!/n");
    return 1;
}

int Menu()
{
    int choice = 0;
    cout<<"/t==================员工管理系统==================="<<endl;
    cout<<"/t1,查询:按特定条件查找员工(按编号)"<<endl;
    cout<<"/t2,修改:按编号对某个员工的某项信息进行修改(按编号)"<<endl;
    cout<<"/t3,插入:加入新员工的信息"<<endl;
    cout<<"/t4,删除:按编号删除已离职的员工的信息"<<endl;
    cout<<"/t5,排序:按特定条件对所有的员工的信息进行排序"<<endl;
    cout<<"/t0,退出:退出该系统"<<endl;
    cout<<"/t================================================="<<endl;
    cout<<endl<<"/tOption -- ";
    cin>>choice;
    return choice;
}   

int main()
{
    int choice = 0, key = 0;
    Employee *em;
    HashTable ht;
//    Hash_Init(ht);
    Hash_Create(ht);
    cout<<"      ------------------欢迎您使用本系统~--------------------"<<endl;
    while(choice = Menu())
    {
        switch(choice)
        {
        case 1:
            cout<<"/t请输入员工编号:";
            cin>>key;
            em = Hash_Search(ht, key);
            if(em != NULL)
            {
                cout<<"/t员工编号 : "<<em->key_code<<endl;;           
                cout<<"/t员工姓名 : "<<em->name<<endl;;
                cout<<"/t性别(N or F) : "<<em->sex<<endl;
                cout<<"/t出生年月日 : "<<em->borndate<<endl;
                cout<<"/t教育程度 : "<<em->education<<endl;
                cout<<"/t职位 : "<<em->position<<endl;
                cout<<"/t电话号码 : "<<em->phone<<endl;
                cout<<"/t居住地址 : "<<em->addr<<endl;
            }
            else
                cout<<"/t没有该员工~ -_-"<<endl;
            break;
        case 2:
            cout<<"/t请输入要修改员工的编号:";
            cin>>key;
            if(Hash_Search(ht, key) != NULL)
                if(-1 != Hash_Modify(ht, key))
                    cout<<"/t修改成功! ^_^"<<endl;
            else
                cout<<"/t没有该员工丫~ -_-"<<endl;
            break;
        case 3:
            em = Record_Input();
            if(Hash_Search(ht, em->key_code) == NULL)
                if(Hash_Insert(ht, em)) cout<<"/t插入成功!^_^"<<endl;
            else
                cout<<"/t已有该员工! 插入失败! -_-"<<endl;
            break;
        case 4:
            cout<<"/t请输入要删除员工的编号:";
            cin>>key;
            if(-1 != Hash_Delete(ht, key))
                cout<<"/t删除成功! ^_^"<<endl;
            else
                cout<<"/t没有改员工丫! -_-"<<endl;
            break;
        case 5:
            Hash_Sort(ht);
            cout<<"/t整理完毕~ ^_^"<<endl;
            break;
        default:
            cout<<"/t您选错了,请看清选项数字~"<<endl;
        }
    }
    cout<<"/t----------感谢使用本系统!---------"<<endl;
    cout<<"/t"<<endl;
    return 0;
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值