哈希算法简称为散列法,也成哈希算法(英译),是将一个大文件映射成一个小串字符。与指纹一样,就是以较短的信息来保证文件的唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。
就像服务器存了10个文本文件,你现在想判断一个新的文本文件和那10个文件有没有一个是一样的。你不可能去比对每个文本里面的每个字节,很有可能,两个文本文件都是5000个字节,但是只有最后一位有所不同,但这样的,你前面4999位的比较就是毫无意义。那一个解决办法,就是在存储那10个文本文件的时候,都将每个文件映射成一个hash字符串。服务器只需要存储10个hash字符串,在判断的时候,只需要判断新的这个文本文件的hash值是否和那10个文件的hash值一致,那就可以解决这个问题了。
简单点说,hash就是将任意长度的消息压缩成某一固定长度的消息摘要的函数。
由于文件是无限的,而映射后的字符串能表示的位数是有限的。因此可能会存在不同的key对应相同的Hash值。这就是存在碰撞的可能。
Hash算法是不可逆的,即不可通过Hash值逆向推出key的值。
struct HashNode
{
int date;
HashNode*pNext;
};
struct HashTable
{
HashNode *value[10] ;
};
//创建哈希表
HashTable* CreateHashTable()
{
HashTable*hashtable = new HashTable;
memset(hashtable, 0, sizeof(HashTable));
return hashtable;
}
//向哈希表中插入元素
void InsetHash(HashTable*hashtable, int value)
{
if (hashtable == nullptr)
{
return;
}
else
{
HashNode *tempNode = hashtable->value[value % 10];
if (tempNode== nullptr)
{
/*tempNode = new HashNode;
tempNode->date = value;
tempNode->pNext = nullptr;*/
hashtable->value[value % 10] = new HashNode;
hashtable->value[value % 10]->date = value;
hashtable->value[value % 10]->pNext = nullptr;
}
else
{
//这一种写法是错误的压根就没有pNext,所以tempNode = tempNode->pNext;应该是先new一个对象出来在进行下面的步骤
/*while (tempNode)
tempNode = tempNode->pNext;
tempNode = new HashNode;
tempNode->date = value;
tempNode->pNext = nullptr;*/
while (tempNode->pNext)
tempNode = tempNode->pNext;
tempNode->pNext = new HashNode;
tempNode->pNext->date = value;
tempNode->pNext->pNext = nullptr;
}
}
}
//查找哈希表中的值
HashNode *FindHash(HashTable*hashtable, int findValue)
{
if (hashtable == nullptr)return nullptr;
HashNode *tempNode = hashtable->value[findValue % 10];
if (tempNode == nullptr)return nullptr;
if (tempNode->date != findValue)
{
while (tempNode->date != findValue && tempNode != nullptr)
tempNode = tempNode->pNext;
}
return tempNode;
}
//删除哈希表中的元素
int DeleteHash(HashTable *hashtable, int findvalue)
{
if (FindHash(hashtable, findvalue))
{
HashNode *node = hashtable->value[findvalue % 10];
if (node == hashtable->value[findvalue % 10])
{
hashtable->value[findvalue % 10] = hashtable->value[findvalue % 10]->pNext;
}
else
{
while (node)
{
if (node->date == findvalue)
break;
node = node->pNext;
}
if (node == nullptr)return -1;
HashNode *tempNode = node;
node = tempNode->pNext;
}
delete node;
return findvalue;
}
}
void clear(HashTable *&hashtable,int len)
{
if (!hashtable)return;
HashNode *pHead;
HashNode *pNode;
for (int i = 0; i < len; i++)
{
pHead = hashtable->value[i];
if (pHead)
{
while (pHead->pNext)
{
pNode = pHead;
pHead = pHead->pNext;
delete pHead;
}
delete hashtable->value[i];
}
}
delete[] hashtable;
hashtable = nullptr;
}
//改变哈希表中的元素
void ChangeHash(HashTable *hashtable, int Newvalue,int OldValue)
{
if (OldValue % 10 != Newvalue % 10) return;
HashNode *node = FindHash(hashtable, OldValue);
node->date = Newvalue;
}
int _tmain(int argc, _TCHAR* argv[])
{
HashTable *hashtable=CreateHashTable();
InsetHash(hashtable, 21);
InsetHash(hashtable, 23);
InsetHash(hashtable, 31);
InsetHash(hashtable, 41);
ChangeHash(hashtable, 51, 41);
HashNode *node = FindHash(hashtable, 31);
if (node != nullptr)
{
cout << node->date << endl;
}
else
{
cout << "没有找到查找的数字" << endl;
}
DeleteHash(hashtable, 21);
DeleteHash(hashtable, 31);
DeleteHash(hashtable, 23);
clear(hashtable, 10);
system("pause");
return 0;
}