• 散列表(哈希表)的实现


    散列函数直接用key%size的形式,size为散列表的大小。

    冲突处理采用平方探测法,为保证可以探测到整个散列表空间,散列表大小设置为4k+3形式的素数。

    当散列表中的元素过多时会造成性能下降,这时应该倍增散列表的大小,重新计算原来散列表中每个元素在新的散列表中的位置。


    散列表的实现


    <span style="font-size:18px;">// HashTable.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<iostream>
    using namespace std;
    
    enum state{
    	empty,
    	deleted,
    	busy,
    };
    
    template<typename T>
    struct HashNode
    {
    	T key;
    	state sta;
    	HashNode()
    	{
    		sta = empty;
    	}
    };
    const int prime_size = 5;
    const static int prime[prime_size] //素数表,形式为4k+3,保证可以探测到整个散列表空间
    ={
    	31, 59, 127, 263, 547
    };
    template<typename T>
    class HashTable
    {
    private:
    	HashNode<T>*hashtable;
    	double alpha;//当前散列表的充满程度
    	int size;//当前散列表的大小
    	int current_busy;
    	double max_alpha;
    	int hash_func(T key)
    	{
    		return key%size;
    	}
    
    	int find_next_prime()
    	{
    		for (int i = 0; i < prime_size; i++)
    		{
    			if (prime[i]>size)
    				return prime[i];
    		}
    		return size;
    	}
    
    	void reHash()//alpha>max_alpha时调整散列表大小
    	{
    		int newsize = find_next_prime();
    		if (newsize == size)
    			return;
    		HashNode<T>*newhashtable = new HashNode<T>[newsize];
    		for (int i = 0; i < size; i++)
    		{
    			if (hashtable[i].sta == busy)
    			{
    				newhashtable[hashtable[i].key % newsize].key = hashtable[i].key;
    				newhashtable[hashtable[i].key % newsize].sta = busy;
    			}
    		}
    		delete[]hashtable;
    		hashtable = newhashtable;
    		size = newsize;
    		alpha =get_alpha();
    	}
    public:
    	
    	HashTable()
    	{
    		max_alpha = 0.80;
    		size = prime[0];
    		alpha = 0;
    		hashtable = new HashNode<T>[size];
    	}
    
    	bool insert(T key)
    	{
    		int count = 0;
    		while (true)
    		{
    			int index = (key + count*count) % size;
    			if (hashtable[index].sta != busy)
    			{
    				hashtable[index].sta = busy;
    				hashtable[index].key = key;
    				current_busy++;
    				alpha = get_alpha();
    				if (alpha > max_alpha)
    					reHash();
    				return true;
    			}
    			if (hashtable[index].sta == busy&&hashtable[index].key == key)
    			{
    				cout<<"HashTable中已经有"<<key<<endl;
    				return false;
    			}
    			index = (key - count*count) % size;
    			while (index < 0)
    			{
    				index += size;
    			}
    			if (hashtable[index].sta != busy)
    			{
    				hashtable[index].sta = busy;
    				hashtable[index].key = key;
    				current_busy++;
    				alpha = get_alpha();
    				if (alpha > max_alpha)
    					reHash();
    				return true;
    			}
    			if (hashtable[index].sta == busy&&hashtable[index].key == key)
    			{
    				cout << "HashTable中已经有" << key << endl;
    				return false;
    			}
    			count++;
    		}
    		
    	}
    
    	int find(T key)
    	{
    		int count = 0;
    		while (true)
    		{
    			int index = (key + count*count) % size;
    			if (hashtable[index].sta != busy)
    			{
    				return -1;
    			}
    			if (hashtable[index].key== key)
    			{
    				return index;
    			}
    			index = (key - count*count) % size;
    			while (index < 0)
    			{
    				index += size;
    			}
    			if (hashtable[index].sta != busy)
    			{
    				return -1;
    			}
    			if (hashtable[index].key == key)
    			{
    				return index;
    			}
    			count++;
    				if (count > size / 2 + 1)
    					return -1;
    		}
    	}
    
    	bool erase(T key)
    	{
    		int index = find(key);
    		if (index >= 0)
    		{
    			hashtable[index].sta = deleted;
    			current_busy--;
    			alpha = get_alpha();
    			return true;
    		}
    		return false;
    	}
    
    	double get_alpha()
    	{
    		return double(current_busy) / double(size);
    	}
    
    
    	~HashTable()
    	{
    		delete[]hashtable;
    	}
    
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HashTable<int>aa;
    	aa.insert(1);
    	aa.insert(2);
    	aa.insert(11);
    	aa.insert(3);
    	aa.insert(5);
    	aa.insert(36);
    	aa.insert(5);
    	cout << aa.find(36) << endl;
    	aa.erase(5) ;
    	//cout << -7 % 4 << endl;
    	system("pause");
    	return 0;
    }
    </span>

    版权声明:

  • 相关阅读:
    Valgrind使用转载 Sanny.Liu
    Caffe模型读取 Sanny.Liu
    JNI动态库生成、编译、查看相关简易资料 Sanny.Liu
    GDB调试,转载一位大牛的东西 Sanny.Liu
    Android处理图片工具(转载) Sanny.Liu
    添加可点击的imagebottom,有个点击动画效果 Sanny.Liu
    去OpenCVManager,大部分为转载,仅当自己学习使用 Sanny.Liu
    转载: vim使用技巧 Sanny.Liu
    结构体数组初始化三种方法,转载 Sanny.Liu
    AsyncTask机制学习 Sanny.Liu
  • 原文地址:https://www.cnblogs.com/walccott/p/4956878.html
Copyright © 2020-2023  润新知