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

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

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

,如左图中所示,假设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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值