哈希表实现电话号码查询 报告Word文件下载.docx
《哈希表实现电话号码查询 报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《哈希表实现电话号码查询 报告Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
通过建立哈希表储存信息,信息储存在节点中,并通过以电话号码为关键字完成查找,并显示出该学生的姓名,电话号码以及家庭住址。
当哈希表中的数据与输入的数据发生冲突时,使用节点向后移一位的方法来解决冲突。
2.系统设计
2.1总体设计
本系统通过设计学生信息类和哈希表类来完成整个系统。
通过学生信息类实现从键盘输入学生的姓名,电话号码以及家庭地址。
将学生的信息储存在建立的哈希节点内,通过多个链表保存,相同信息的保存在同一个节点内。
然后通过以电话号码为关键字建立哈希表。
当输入的信息与表内储存的信息发生冲突时,通过建立新的节点并向后移一位的方法来解决冲突。
系统界面
2.2详细设计
首先初始化哈希表,并建立新的节点(哈希表的容量不能大于1001,否则哈希表初始化失败),从键盘输入学生的姓名,电话号码以及家庭住址,所输入的变量无法被改变。
然后将建立的节点插入哈希表里。
2.2.1程序头文件
#include<
iostream.h>
stdlib.h>
cstdio>
sstream>
#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
HASHTABLE*_hashTable;
//哈希首地址
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编码
头文件
学生信息类
学生信息表
Student:
Student()
memset(_name,0,MAX_LEN);
memset(_phone,0,MAX_LEN);
memset(_addr,0,MAX_LEN);
}
constchar*Student:
getName()
return_name;
getPhone()
return_phone;
getAddr()
return_addr;
voidStudent:
setName(constchar*name)
strcpy(this->
_name,name);
setPhone(constchar*phone)
_phone,phone);
setAddr(constchar*addr)
_addr,addr);
//////////////////////////////////////////////////////////////////////////
哈希节点,建立数据存储的节点
哈希表结构定义
哈希表管理类
拿到字符串存在的节点
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;
//链表队列一条链为一个散列位置
p_node=(LISTNODE**)newint[table_size];
//每一个散列链初始化
for(inti=0;
i<
head_ht->
n_tablesize;
i++)
{
head_ht->
p_node[i]=NULL;
}
_hashTable=head_ht;
returntrue;
//清理
voidCHashTableManage:
hashtable_clear()//0
if(_hashTable==NULL)
return;
//每一个散列链free
_hashTable->
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;
returnNULL;
intpos=hashtable_hash(phone,_hashTable->
n_tablesize);
list=_hashTable->
p_node[pos];
//链表查找
while(list!
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
_info.getAddr(),list_pos->
_info.getAddr())==0
_info.getName(),list_pos->
_info.getName())==0)
list_pos->
count++;
returnpos;
//不存在
LISTNODE*node=hashtable_newnode(pNode);
node->
p_next=_hashTable->
_hashTable->
p_node[pos]=node;
returnpos;
//哈希函数
//得到字符串在哈希表中的位置
hashtable_hash(char*str,inttablesize)
unsignedinthash_val=0;
while(*str!
='
\0'
)
hash_val+=(hash_val<
<
5)+*str++;
intpos=hash_val%tablesize;
//得到新一个新节点
hashtable_newnode(LISTNODE*str)
//插入节点初始化
LISTNODE*insert_node=(LISTNODE*)malloc(sizeof(LISTNODE));
insert_node->
p_next=NULL;
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<
"
哈希初始化失败"
endl;
return1;
cout<
**********************************************************************************"
<
学生信息管理(哈希表实现)>
>
"
>
按任意键开始"
**********************************************************************************"
getchar();
while
(1)
system("
cls"
);
......................."
endl;
.<
1>
添加学生信息."
2>
查询学生信息."
0>
退出."
charkey=getchar();
switch(key)
case'
1'
LISTNODEinfo;
charbuf[MAX_LEN];
memset(&
info,0,sizeof(info));
cout<
----请输入学生信息[姓名]"
cin>
buf;
info._info.setName(buf);
----请输入学生信息[电话]"
info._info.setPhone(buf);
----请输入学生信息[地址]"
info._info.setAddr(buf);
strcpy(info._phone,info._info.getPhone());
_manage.hashtable_insert(&
info);
----恭喜写入成功!
!
按任意键确认"
getchar();
2'
----请输入查询条件[电话]"
//找到这个字符串具体位置
LISTNODE*node=_manage.hashtable_find(buf);
if(node==0)
{
cout<
----没有查询到相关数据!
}else
----查询到以下数据----"
while(node!
{
cout<
---------------------------------------------------------------"
----相同信息数:
node->
count<
----学生姓名:
_info.getName()<
----电话号码:
_info.getPhone()<
----学生地址:
_info.getAddr()<
node=node->
}
----查询完毕!
}
0'
_manage.hashtable_clear();
return0;
default:
----输入错误,请确认!
按任意键重新开始..."
return0;
3.2测试
本次测试数据为:
姓名:
张三
电话号码:
111111
家庭住址:
北京
李四
222222
上海
王五
333333
广州
程序界面