您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法分析学习笔记--第五章--散列---分离链接法

2014-06-13 21:56 330 查看
在散列表中,如果当一个元素被插入时,另一个元素已经存在(散列值相同,也就是键相同),那么就会产生一个冲突,这个冲突需要消除。消除这种冲突的方法有多种,本篇我们将讨论分离链接法。

其做法是将散列到同一个值的所有元素保存到一个表中。这个表可以是链表、栈、队列、二叉树,甚至另外一个散列表。下面我们来举一个例子,该例子中散列表中的表为链表。


,如左图中所示,假设hash函数为data%HashTableSize,其中HashTableSize = 10,则1、81等对应的哈希值相同,都是1,那么就在hash表m_lisi[1]中依次存放。hash表中的10个链表,它们的头结点可以赋值,也可以不赋值。

下面见代码:

//hash1.h
//哈希表的初始化,插入结点、查找结点、删除结点
#include <iostream>
using namespace std;
template<typename T>
class ListNode
{
public:
T m_data;
ListNode *m_next;
public:
ListNode()
{
m_data=0;
m_next = NULL;
}
};
template<typename T>
class HashTbl
{
public:
int m_TableSize;
ListNode<T> **m_TheList;
public:
HashTbl<T> *InitializeTable(int TableSize);
void Insert(T data);
ListNode<T> * Find(T data);
int Hash(int data);
void Delete(T data);
};

template<typename T>
int HashTbl<T>::Hash(int data)
{
return data % m_TableSize;
}

template<typename T>
ListNode<T> *  HashTbl<T>::Find(T data)
{
ListNode<T> *Position = NULL;
Position = m_TheList[Hash(data)];
Position = Position->m_next;
if(Position == NULL)
{
return NULL;
}
while(Position !=NULL && data != Position->m_data)
{
Position = Position->m_next;
}
return Position;
}

template<typename T>
HashTbl<T> *HashTbl<T>::InitializeTable(int tableSize)
{
int i;
m_TableSize = tableSize;
m_TheList = new ListNode<T> *[tableSize];//为hash表分配tablesize个头结点,hash表的变量指向其中的一个结构
if(m_TheList == NULL)
{
cout << "Out of memory" << endl;
return NULL;
}
for(i = 0;i < tableSize; ++i)
{
m_TheList[i] = new ListNode<T>();	//为每个头结点分配空间
if(m_TheList[i] == NULL)
{
cout << "Out of memory" << endl;
//此处因该将其他已经分配的空间都删除掉
return NULL;
}
else
m_TheList[i]->m_next = NULL;
}
return this;
}

template<typename T>
void HashTbl<T>::Insert(T data)
{
ListNode<T> *Position = NULL;
if(Find(data) == NULL)
{
int i = this->Hash(data);
ListNode<T> *L = m_TheList[i];
ListNode<T> *p = new ListNode<T>();
if(p == NULL)
{
cout << "out of memory" <<endl;
return;
}
p->m_next = L->m_next;
p->m_data = data;
L->m_next = p;
}
else
{
cout << "node has been in hashtable!" << endl;
}
}
template<typename T>
void HashTbl<T>::Delete(T data)
{
ListNode<T> *Position = NULL;
ListNode<T> *tt;
if(Find(data) != NULL)
{
Position = m_TheList[Hash(data)];
Position = Position->m_next;
while(Position->m_next != NULL )
{
if(Position->m_next->m_data == data)
{
tt = Position->m_next->m_next;
delete Position->m_next;
Position->m_next = tt;
break;
}
Position = Position->m_next;
}
}
else
{
cout << "can not find nodes in hashtable!" << endl;
}
}
测试函数:

#include "hash1.h"
int main()
{
HashTbl<int> h;
h.InitializeTable(10);
for(int i = 0; i < 100; ++i)
{
h.Insert(i);
}
h.Delete(81);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐