您的位置:首页 > 其它

哈希(hash)算法的学习(二)

2013-11-01 17:20 429 查看
这一部分主要是贴出代码

#ifndef HASH_TABLE_H
#define  HASH_TABLE_H
#include <string>
using namespace std;
class Key:public string
{
public:
char key_letter(int position) const;
void make_blank();
Key(const string & str);
Key();
string str;
string& operator = (const string& str_1){str = str_1; return str;}
};
int Hash(const Key& target); //简单的哈希函数

enum Error_code {success, duplicate_error, overflow, not_exist};
typedef string Record;
const int hash_size = 11;	//哈希表大小,要选择质数

class Hash_table
{
public:
Hash_table();
void clear();
Error_code insert(const Record& new_entry);
Error_code retrieve(const Key &target, Record& found) const;
Error_code remove(const Key &target);
private:
Record table[hash_size];
bool empty[hash_size];	//用于指示被删除的元素,如果元素被删,则赋值为true
};
#endif

类的实现 ------------------Hash_table.cpp----------------------
#include "Hash_table.h"
#include <iostream>
//Key类的实现
Key::Key(const string & str)
{
this->str = str;
}
Key::Key()
{
str = " ";
}
char Key::key_letter(int position) const
{
int num = str.length();
if(position>=num || position<0)
return 0;
else
return str.at(position);
}
void Key::make_blank()
{
str = " ";
}
//hash函数的实现
int Hash(const Key& target)
{
int value = 0;
for(int position=0; position<8; position++)
value = 4*value + target.key_letter(position);
return value % hash_size;
}
//Hash_table类的实现
Hash_table::Hash_table()
{//初始化如果Record是自定义的类可以考虑重载操作符‘=’
for(int i=0; i<hash_size; i++)
{
table[i] = " ";
empty[i] = false;
}
}
Error_code Hash_table::insert(const Record& new_entry)
{
Error_code result = success;
int probe_count = 0,	//记录探测次数,如果次数超过(hash_size+1)/2认为hashtable已满
increment = 1,		//二次探测的增量
probe;				//当前探测的位置
// 	Key null;
// 	null.make_blank(); //
Record null = " ";
probe = Hash(new_entry);
/*	cout<<probe<<"  ";*/
while(table[probe]!=null			// Is the location empty
&& table[probe]!=new_entry		// Duplicate key?
&& probe_count<=(hash_size+1)/2) // Has overflow occurred?
{
probe_count++;
probe = (probe+increment)% hash_size;
increment+=2;
}
if(table[probe]==null){ table[probe] = new_entry; empty[probe]=false;}
else if(table[probe]==new_entry) result = duplicate_error;
else result = overflow;
return result;
}
Error_code Hash_table::retrieve(const Key &target, Record& found) const
{//hash表的查询操作
Error_code result = success;
int probe, increment=1, probe_count=0;
Record null = " ";
probe = Hash(target);
while (table[probe]!= target.str
&& (table[probe]!= null || empty[probe]==true)
&& probe_count<(hash_size+1)/2)
{
probe_count++;
probe = (probe + increment)% hash_size;
increment+=2;
}
if(table[probe]==target.str) found = target.str;
else if(table[probe] == null) result = not_exist;
else result = not_exist;

return result;
}
Error_code Hash_table::remove(const Key &target)
{//hash表删除操作
Error_code result = success;
int probe = 0, increment = 1, probe_count = 0;
string null = " ";
probe = Hash(target);
while(table[probe]!=target.str
&& (table[probe]!=null || empty[probe]==true)
&& probe_count<(hash_size+1)/2)
{
probe = (probe + increment)% hash_size;
probe_count++;
increment += 2;
}
if(table[probe]==target.str)
{
empty[probe] = true;	//表示已删除
table[probe] = null;	//清空数据
result = success;
}
else  result = not_exist;

return result;
}

测试程序 ----------------test.cpp----------------------

#include <iostream>
#include <cstdlib>
#include <string>
#include "Hash_table.h"
using namespace std;

string str[11] = {"widjis","asdw","vfgh","tybng","mukut","qdtvc",
"tygvmui","agtxi","opgded","nexop","fpoenb"};//"mnexop"
Hash_table tb;
Key key;
string str_t;
void print_element();
int main()
{
for(int i=0; i<11; i++)
tb.insert(str[i]);
cout<<"读取测试"<<endl;

print_element();

cout<<"删除测试"<<endl;
key = "agtxi";
Key key1("widjis");
Key key2("tybng");

tb.remove(key);
tb.remove(key1);
tb.remove(key2);

print_element();

cout<<"插入数据 dfnk"<<endl;
tb.insert("dfnk");//"kdfnk"

print_element();

key = "dfnk";
tb.retrieve(key, str_t);
cout<<str_t<<endl;
system("pause");
return 0;
}
void print_element()
{
for(int i=0; i<11; i++)
{
key = str[i];
if(tb.retrieve(key, str_t) == not_exist)	//如果元素不存在则用符号<>标注
cout<<'<'<<str[i]<<"> ";
else
cout<<str_t<<" ";
}
cout<<endl;
}

测试结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: