哈希表实现电话号码查询 报告.docx
《哈希表实现电话号码查询 报告.docx》由会员分享,可在线阅读,更多相关《哈希表实现电话号码查询 报告.docx(19页珍藏版)》请在冰豆网上搜索。
哈希表实现电话号码查询报告
《数据结构》
课程设计报告书
题目:
哈希表存储的电话号码查询
专业:
学号:
学生姓名:
指导教师:
完成日期:
1.实训题目………………………………………………
1.1实训要求………………………………………….
1.2需求分析………………………………………….
2.系统设计………………………………………………
2.1总体设计…………………………………………..
2.2详细设计…………………………………………..
2.2.1程序头文件…………………………………..
2.2.2学生信息类及哈希表类……………………..
2.2.3主函数流程…………………………………..
3.系统实现……………………………………………….
3.1编码………………………………………………..
3.2测试………………………………………………..
4.归纳总结……………………………………………….
4.1实训中遇到的问题以及解决办法………………..
4.2感想和心得体会…………………………………..
5.参考资料………………………………………………
1.实训题目
1.1实训要求
⏹设每个记录有以下数据项:
用户名、电话、地址;
⏹从键盘输入各记录,以电话号码为关键字建立哈希表;
⏹采用链地址法方法解决冲突;
⏹能够查找并显示给定电话号码的相关记录。
1.2需求分析
本次实验要求采用哈希表完成信息的查找和储存,哈希表即为散列表。
本程序采用学生信息管理为例,设每个学生有电话号码,学生姓名,家庭住址三个信息。
通过建立哈希表储存信息,信息储存在节点中,并通过以电话号码为关键字完成查找,并显示出该学生的姓名,电话号码以及家庭住址。
当哈希表中的数据与输入的数据发生冲突时,使用节点向后移一位的方法来解决冲突。
2.系统设计
2.1总体设计
本系统通过设计学生信息类和哈希表类来完成整个系统。
通过学生信息类实现从键盘输入学生的姓名,电话号码以及家庭地址。
将学生的信息储存在建立的哈希节点内,通过多个链表保存,相同信息的保存在同一个节点内。
然后通过以电话号码为关键字建立哈希表。
当输入的信息与表内储存的信息发生冲突时,通过建立新的节点并向后移一位的方法来解决冲突。
系统界面
2.2详细设计
首先初始化哈希表,并建立新的节点(哈希表的容量不能大于1001,否则哈希表初始化失败),从键盘输入学生的姓名,电话号码以及家庭住址,所输入的变量无法被改变。
然后将建立的节点插入哈希表里。
2.2.1程序头文件
#include
#include
#include
#include
#defineMAX_LEN60
2.2.2学生信息类及哈希表类
学生信息类(其中输入的信息无法改变)
classStudent
{
private:
char_name[MAX_LEN];//姓名
char_phone[MAX_LEN];//电话
char_addr[MAX_LEN];//地址
public:
Student();
constchar*getName();//变量不允许被改变
constchar*getPhone();
constchar*getAddr();
voidsetName(constchar*name);
voidsetPhone(constchar*phone);
voidsetAddr(constchar*addr);
};
哈希表类
其中含有初始化哈希表函数,清空函数,插入节点函数,获取节点位置函数组成。
classCHashTableManage
{
private:
HASHTABLE*_hashTable;//哈希首地址
public:
CHashTableManage();
boolhashtable_init(inttable_size);//初始化
voidhashtable_clear();//清理
//拿到这个字符串存在的节点
LISTNODE*hashtable_find(char*phone);
//插入一个结点
inthashtable_insert(LISTNODE*pNode);
protected:
LISTNODE*CHashTableManage:
:
hashtable_newnode(LISTNODE*str);
//哈希函数
//得到字符串在哈希表中的位置
inthashtable_hash(char*str,inttablesize);
};
哈希节点结构体为:
structLISTNODE
{
intn_value;//
intcount;//保存的个数
char_phone[MAX_LEN];//key
Student_info;//学生信息
LISTNODE*p_next;//下一个结点的地址
};
哈希表结构体为:
structHASHTABLE
{
intn_tablesize;
LISTNODE**p_node;
};
2.2.3主函数流程
3.系统实现
3.1编码
头文件
#include
#include
#include
#include
#defineMAX_LEN60
学生信息类
classStudent
{
private:
char_name[MAX_LEN];//姓名
char_phone[MAX_LEN];//电话
char_addr[MAX_LEN];//地址
public:
Student();
constchar*getName();//变量不允许被改变
constchar*getPhone();
constchar*getAddr();
voidsetName(constchar*name);
voidsetPhone(constchar*phone);
voidsetAddr(constchar*addr);
};
学生信息表
Student:
:
Student()
{
memset(_name,0,MAX_LEN);
memset(_phone,0,MAX_LEN);
memset(_addr,0,MAX_LEN);
}
constchar*Student:
:
getName()
{
return_name;
}
constchar*Student:
:
getPhone()
{
return_phone;
}
constchar*Student:
:
getAddr()
{
return_addr;
}
voidStudent:
:
setName(constchar*name)
{
strcpy(this->_name,name);
}
voidStudent:
:
setPhone(constchar*phone)
{
strcpy(this->_phone,phone);
}
voidStudent:
:
setAddr(constchar*addr)
{
strcpy(this->_addr,addr);
}
//////////////////////////////////////////////////////////////////////////
哈希节点,建立数据存储的节点
structLISTNODE
{
intn_value;//
intcount;//保存的个数
char_phone[MAX_LEN];//key
Student_info;//学生信息
LISTNODE*p_next;//下一个结点的地址
};
//////////////////////////////////////////////////////////////////////////
哈希表结构定义
structHASHTABLE
{
intn_tablesize;
LISTNODE**p_node;
};
哈希表管理类
classCHashTableManage
{
private:
HASHTABLE*_hashTable;//哈希首地址
public:
CHashTableManage();
boolhashtable_init(inttable_size);//初始化
voidhashtable_clear();//清理
拿到字符串存在的节点
LISTNODE*hashtable_find(char*phone);
//插入一个结点
inthashtable_insert(LISTNODE*pNode);
protected:
LISTNODE*CHashTableManage:
:
hashtable_newnode(LISTNODE*str);
//哈希函数
//得到字符串在哈希表中的位置
inthashtable_hash(char*str,inttablesize);
};
//////////////////////////////////////////////////////////////////////////
CHashTableManage:
:
CHashTableManage()
:
_hashTable(0)
{
}
初始化哈希表,建立一个散列表
boolCHashTableManage:
:
hashtable_init(inttable_size)
{
//表头
HASHTABLE*head_ht;
head_ht=(HASHTABLE*)new(HASHTABLE);
if(head_ht==NULL)
returnfalse;
//元素总数尽量素数保证mod尽可能均匀
head_ht->n_tablesize=table_size;
//链表队列一条链为一个散列位置
head_ht->p_node=(LISTNODE**)newint[table_size];
//每一个散列链初始化
for(inti=0;in_tablesize;i++)
{
head_ht->p_node[i]=NULL;
}
_hashTable=head_ht;
returntrue;
}
//清理
voidCHashTableManage:
:
hashtable_clear()//0
{
if(_hashTable==NULL)
return;
//每一个散列链free
for(inti=0;i<_hashTable->n_tablesize;i++)
{
if(_hashTable->p_node[i])
{
LISTNODE*list=_hashTable->p_node[i];
//当前链表不空
while(list!
=NULL)
{
//取得下一个
LISTNODE*tempnode=list->p_next;
//free当前位置
if(list)
deletelist;
//指向下一个
list=tempnode;
}
}
}
链表队列free
if(_hashTable->p_node)
{
delete(_hashTable->p_node);
_hashTable->p_node=NULL;
}
哈希头节点free
if(_hashTable)
{
delete(_hashTable);
_hashTable=NULL;
}
}
//拿到这个字符串存在的节点
LISTNODE*CHashTableManage:
:
hashtable_find(char*phone)//2
{
//哪一条链表
LISTNODE*list=NULL;
if(_hashTable==NULL)
returnNULL;
intpos=hashtable_hash(phone,_hashTable->n_tablesize);
list=_hashTable->p_node[pos];
//链表查找
while(list!
=NULL)
{
if(strcmp(phone,list->_phone)==0)//比较
break;
list=list->p_next;
}
returnlist;
}
/插入一个新的结点
intCHashTableManage:
:
hashtable_insert(LISTNODE*pNode)//1
{
intpos=hashtable_hash(pNode->_phone,_hashTable->n_tablesize);
LISTNODE*list_pos=_hashTable->p_node[pos];
将插入的节点与哈希表内的节点比较,如有冲突则将插入的节点向表后移一位
for(;list_pos!
=NULL;list_pos=list_pos->p_next)
{
if(strcmp(list_pos->_phone,pNode->_phone)==0
&&strcmp(pNode->_info.getPhone(),list_pos->_info.getPhone())==0
&&strcmp(pNode->_info.getAddr(),list_pos->_info.getAddr())==0
&&strcmp(pNode->_info.getName(),list_pos->_info.getName())==0)
{
list_pos->count++;
returnpos;
}
}
//不存在
LISTNODE*node=hashtable_newnode(pNode);
node->p_next=_hashTable->p_node[pos];
_hashTable->p_node[pos]=node;
returnpos;
}
//哈希函数
//得到字符串在哈希表中的位置
intCHashTableManage:
:
hashtable_hash(char*str,inttablesize)
{
unsignedinthash_val=0;
while(*str!
='\0')
hash_val+=(hash_val<<5)+*str++;
intpos=hash_val%tablesize;
returnpos;
}
//得到新一个新节点
LISTNODE*CHashTableManage:
:
hashtable_newnode(LISTNODE*str)
{
//插入节点初始化
LISTNODE*insert_node=(LISTNODE*)malloc(sizeof(LISTNODE));
insert_node->p_next=NULL;
insert_node->count=1;
strcpy(insert_node->_phone,str->_info.getPhone());
memcpy(&insert_node->_info,&str->_info,sizeof(str->_info));
returninsert_node;
}
//////////////////////////////////////////////////////////////////////////
主函数
intmain(void)
{
CHashTableManage_manage;
//初始一个个链表的哈希表size最好为素数
//head=hashtable_init(1001);
if(!
_manage.hashtable_init(1001))
{
cout<<"哈希初始化失败"<return1;
}
cout<<"**********************************************************************************"<cout<<"<<<<<<<<<<学生信息管理(哈希表实现)>>>>>>>>>>"<cout<<"<<<<<<<<<<>>>>>>>>>>"<cout<<"<<<<<<<<<<>>>>>>>>>>"<cout<<"<<<<<<<<<<>>>>>>>>>>"<cout<<"按任意键开始"<cout<<"**********************************************************************************"<getchar();
while
(1)
{
system("cls");
cout<<"......................."<cout<<".<1>添加学生信息."<cout<<".<2>查询学生信息."<cout<<".<0>退出."<cout<<"......................."<charkey=getchar();
switch(key)
{
case'1':
{
LISTNODEinfo;
charbuf[MAX_LEN];
memset(&info,0,sizeof(info));
cout<<"----请输入学生信息[姓名]"<cin>>buf;
info._info.setName(buf);
cout<<"----请输入学生信息[电话]"<cin>>buf;
info._info.setPhone(buf);
cout<<"----请输入学生信息[地址]"<cin>>buf;
info._info.setAddr(buf);
strcpy(info._phone,info._info.getPhone());
_manage.hashtable_insert(&info);
cout<<"----恭喜写入成功!
!
!
按任意键确认"<getchar();
}
break;
case'2':
{
cout<<"----请输入查询条件[电话]"<charbuf[MAX_LEN];
cin>>buf;
//找到这个字符串具体位置
LISTNODE*node=_manage.hashtable_find(buf);
if(node==0)
{
cout<<"----没有查询到相关数据!
!
!
按任意键确认"<}else
{
cout<<"----查询到以下数据----"<while(node!
=NULL)
{
cout<<"---------------------------------------------------------------"<cout<<"----相同信息数:
"<count<cout<<"----学生姓名:
"<_info.getName()<cout<<"----电话号码:
"<_info.getPhone()<cout<<"----学生地址:
"<_info.getAddr()<node=node->p_next;
}
cout<<"---------------------------------------------------------------"<cout<<"----查询完毕!
!
!
按任意键确认"<}
getchar();
getchar();
}
break;
case'0':
{
_manage.hashtable_clear();
return0;
}
break;
default:
{
cout<<"----输入错误,请确认!
!
按任意键重新开始..."<getchar();
getchar();
}
break;
}
}
return0;
}
3.2测试
本次测试数据为:
姓名:
张三
电话号码:
111111
家庭住址:
北京
姓名:
李四
电话号码:
222222
家庭住址:
上海
姓名:
王五
电话号码:
333333
家庭住址:
广州
程序界面