今天实际code温习了下Hash,主要4个功能是:给定一个整数n创建可以存放n个值的Hash表,在表中插入元素,查找对应元素,显示Hash表。
hash.h如下:
#ifndef _HASH // Specifies that the minimum required platform is Windows Vista. #define _HASH // Change this to the appropriate value to target other versions of Windows. #define SUCCESS 0 #define UNSUCCESS -1 #define NULLKEY -1 template struct ElemType { T Key; //关键字 /* //其它 */ }; template class LHSearch { private: ElemType * HT; int count; int size; public: LHSearch(); ~LHSearch(); void InitHashTable(int n); int Hash(T key); //计算hash地址 void Collision(int &s); //冲突,计算下一个地址 int Search(T key,int &s); //Hash 查找 int Insert(ElemType e); //元素插入 void Display(); }; #endif
########################################################
HashSearch.cpp如下:
// HashSearch.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include "hash.h" using namespace std; template LHSearch::LHSearch() { HT=NULL; size=0; count=0; } template LHSearch::~LHSearch() { delete []HT; count=0; } template void LHSearch::InitHashTable(int n) { size=n; HT=new ElemType[size]; for(int i=0;i HT[i].Key=NULLKEY; } template int LHSearch::Hash(T key) { return key%size; } template void LHSearch::Collision(int &s) { s=(++s)%size; //注意是++s,不是s++ } template int LHSearch::Search(T key,int &s) { s=Hash(key); int start=-1; int flag=1; while((HT[s].Key!=-1)&&(key!=HT[s].Key)&&(s!=start)) //改进部分,如果当前插入的位置有有效数值,则循环进行检查, { //start标记当前最开始冲突的位置,然后循环增加指针s=(++s)%size; if(flag) //如果到最初的start位置仍然没有找到可用位置,则退出循环。 { count=0; start=s; } Collision(s); //发生冲突,则S循环+1 } if(HT[s].Key==key) return 1; else return 0; } template int LHSearch::Insert(ElemType e) { int s; if(count==size) { cout<<"表满,不能插入!"< return UNSUCCESS; } else { s=Hash(e.Key); int f; f=Search(e.Key,s); if(f) { cout<<"表中已存在该元素,不能插入!"< return UNSUCCESS; } else { HT[s].Key=e.Key; cout<<"插入成功!"< count++; return SUCCESS; } } } template void LHSearch::Display() { for(int i=0;i { cout<<<"/t"; if(HT[i].Key!=-1) cout< else cout<<"/t"; cout< } } int _tmain(int argc, _TCHAR* argv[]) { int m; int key; int s=0; ElemType e; LHSearch a; cout<<"必须先创建哈希表/n"; do{ cout<<"----1.创建------------------------/n" <<"----2.插入------------------------/n" <<"----3.查找------------------------/n" <<"----4.显示------------------------/n" <<"----5.退出------------------------/n" <<"plz!"; cin>>m; switch(m) { case 1: cout<<"请输入表容量(>=13的整数)/n"; int num; cin>>num; a.InitHashTable(num); cout<<"依次输入表元素,-1结束:/n"; for(cin>>e.Key;e.Key!=-1;cin>>e.Key) a.Insert(e); break; case 2: cout<<"输入元素:/n"; cin>>e.Key; a.Insert(e); break; case 3: cout<<"请输入查找关键字:/n"; cin>>key; if(a.Search(key,s)) cout<<"找到!/n"; else cout<<"不存在,未找到!/n"; break; case 4: a.Display(); break; case 5: cout<<"结束!/n"; break; } }while(m!=5); return 0; }
以上实现的Hash表功能ElemType只有一个Key,用-1来表示NULLKEY,也就是未使用过的值。我们可以加入其他变量来标识它,bool used, 用过则true,没用过则false。
hash.h
#ifndef _HASH // Specifies that the minimum required platform is Windows Vista. #define _HASH // Change this to the appropriate value to target other versions of Windows. #define SUCCESS 0 #define UNSUCCESS -1 #define NULLKEY -1 template struct ElemType { T Key; //关键字 bool Used; //用过 与否 /* //其它 */ }; template class LHSearch { private: ElemType * HT; int count; int size; public: LHSearch(); ~LHSearch(); void InitHashTable(int n); int Hash(T key); //计算hash地址 void Collision(int &s); //冲突,计算下一个地址 int Search(T key,int &s); //Hash 查找 int Insert(ElemType e); //元素插入 void Display(); }; #endif
#############################################
// HashSearch.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include "hash.h" using namespace std; template LHSearch::LHSearch() { HT=NULL; size=0; count=0; } template LHSearch::~LHSearch() { delete []HT; count=0; } template void LHSearch::InitHashTable(int n) { size=n; HT=new ElemType[size]; for(int i=0;i { HT[i].Key=NULLKEY; HT[i].Used=false; } } template int LHSearch::Hash(T key) { return key%size; } template void LHSearch::Collision(int &s) { s=(++s)%size; } template int LHSearch::Search(T key,int &s) { s=Hash(key); int start=-1; int flag=1; while((HT[s].Used==true)&&(key!=HT[s].Key)&&(s!=start)) //改进部分,如果当前插入的位置有有效数值,则循环进行检查, { //start标记当前最开始冲突的位置,然后循环增加指针s=(++s)%size; if(flag) //如果到最初的start位置仍然没有找到可用位置,则退出循环。 { flag=0; start=s; } Collision(s); } if(HT[s].Key==key) return 1; else return 0; } template int LHSearch::Insert(ElemType e) { int s; if(count==size) { cout<<"表满,不能插入!"< return UNSUCCESS; } else { s=Hash(e.Key); int f; f=Search(e.Key,s); if(f) { cout<<"表中已存在该元素,不能插入!"< return UNSUCCESS; } else { HT[s].Key=e.Key; HT[s].Used=true; //插入成功置 Used cout<<"插入成功!"< count++; return SUCCESS; } } } template void LHSearch::Display() { for(int i=0;i { cout<<<"/t"; if(HT[i].Used==true) cout< else cout<<"/t"; cout< } } int _tmain(int argc, _TCHAR* argv[]) { int m; int key; int s=0; ElemType e; LHSearch a; cout<<"必须先创建哈希表/n"; do{ cout<<"----1.创建------------------------/n" <<"----2.插入------------------------/n" <<"----3.查找------------------------/n" <<"----4.显示------------------------/n" <<"----5.退出------------------------/n" <<"plz!"; cin>>m; switch(m) { case 1: cout<<"请输入表容量(>=13的整数)/n"; int num; cin>>num; a.InitHashTable(num); cout<<"依次输入表元素,0结束:/n"; for(cin>>e.Key;e.Key!=0;cin>>e.Key) a.Insert(e); break; case 2: cout<<"输入元素:/n"; cin>>e.Key; a.Insert(e); break; case 3: cout<<"请输入查找关键字:/n"; cin>>key; if(a.Search(key,s)) cout<<"找到!/n"; else cout<<"不存在,未找到!/n"; break; case 4: a.Display(); break; case 5: cout<<"结束!/n"; break; } }while(m!=5); return 0; }
本文介绍了哈希表的基本概念及其实现方法,通过C++代码详细展示了如何创建哈希表、插入元素、查找元素以及显示哈希表的过程。同时,还探讨了如何通过增加标志位来优化哈希表的存储效率。

1128

被折叠的 条评论
为什么被折叠?



