精华内容
下载资源
问答
  • 哈希表 用链地址法解决冲突:(哈希函数是按名字第一个大写字母分的) 输入内容:学生的姓名跟成绩 操作:插入、修改、查找、删除学生;以及输出哈希
  • 哈希函数: 使用特定的哈希...链地址法: 开放地址法中,通过在哈希表中寻找一个空位解决哈希冲突问题。另一个方法是在哈希表每个单元中设置链表。某个数据项的关键字还是像通常一样映射到哈希表的单元,而数据项本...

    哈希函数: 使用特定的哈希算法,将关键字哈希化,压缩到一个较小的范围

    哈希表: 使用哈希算法, 把一个大范围的数字哈希化成一个小范围的数字。 这个小范围对应着数组的下标。 使用哈希函数向数组插入数据后, 这个数组称为哈希表

    链地址法: 开放地址法中,通过在哈希表中寻找一个空位解决哈希冲突问题。另一个方法是在哈希表每个单元中设置链表。某个数据项的关键字还是像通常一样映射到哈希表的单元,而数据项本身插入到这个单元的链表中

    装填因子: 链地址法中的装填因子(数据项数和哈希表容量的比值)与开发地址法的不同。 在链地址法中,需要在有N个单元的数组中装入N个或更多的数据项;因此装填因子一般为1,或比一大。 这没问题;因为,某些位置包含的链表中包含两个或两个以上的数据项。

    下面将使用链地址法 实现哈希表并解决哈希冲突问题

    1. 创建一个link类

    public class Link {
    
        private int iData;
        public Link next;
    
    
        public Link(int it){
            this.iData = it;
        }
    
        public int getKey(){
            return iData;
        }
    
        public void displayLink(){
           System.err.print(iData+" ");
        }
    }

    2. 创建一个SortedList类

    public class SortedList {
    
        private Link first;
    
    
        public void SortedList(){
            first = null;
        }
    
        public void insert(Link theLink){
            int key = theLink.getKey();
            Link previous =null;
            Link current = first;
    
            while(current !=null && key> current.getKey()){
                previous = current;
                current = current.next;
            }
            if (previous ==null){
                first = theLink;
            }else{
                previous.next = theLink;
                theLink.next = current;
            }
        }
    
        public void delete(int key){
            Link previous = null;
            Link current = first;
            while(current !=null && key != current.getKey()){
                previous = current;
                current = current.next;
            }
    
            if (previous == null){
                first = first.next;
            }else{
                previous.next = current.next;
            }
        }
    
        public Link find(int key){
            Link current = first;
            while(current!=null && current.getKey()<= key){
                if (current.getKey() == key){
                    return current;
                }
                current = current.next;
            }
            return null;
        }
    
        public void displayList(){
            System.out.print("List (first --> last):");
            Link current = first;
            while(current!=null ){
                current.displayLink();
                current = current.next;
            }
            System.out.print("");
        }
    }
    

    3. 使用链地址法实现哈希表

    public class LinkHashTable {
    
    
        private SortedList[] hashArray;
        private int arraySize;
    
    
        public LinkHashTable(int size){
            arraySize = size;
            hashArray = new SortedList[arraySize];
            for (int j=0; j<arraySize; j++){
                hashArray[j] = new SortedList();
            }
        }
    
        public void displayTable(){
            for (int j = 0; j<arraySize;j++){
                System.out.print(j+ ". ");
                hashArray[j].displayList();
            }
        }
    
        public int hashFunc(int key){
            return key % arraySize;
        }
    
        public void insert (Link theLink){
            int key = theLink.getKey();
            int hashVal = hashFunc(key);
            hashArray[hashVal].insert(theLink);
        }
    
        public void delete(int key){
            int hashVal = hashFunc(key);
            hashArray[hashVal].delete(key);
        }
    
        public Link find(int key){
            int hashVal = hashFunc(key);
            Link theLink = hashArray[hashVal].find(key);
            return theLink;
        }
    }

    4. 编辑测试类

    public class HashChainApp {
    
        public static void main(String[] args) throws IOException{
            int aKey;
            Link aDataItem;
    
            int size, n, keysPerCell = 100;
            System.out.print("Enter size of hash table: ");
            size = getInt();
            System.out.print("Enter initial number of items: ");
            n =getInt();
    
            LinkHashTable theHashTable = new LinkHashTable(size);
    
            for (int j=0; j<n; j++){
                aKey = (int) (Math.random() * keysPerCell * size);
                 aDataItem = new Link(aKey);
                 theHashTable.insert(aDataItem);
            }
    
            while(true){
                System.out.print("Enter first letter of");
                System.out.print("  show, insert, delete, or find: ");
                char choice = getChar();
                switch(choice){
                    case 's':
                        theHashTable.displayTable();
                        break;
                    case 'i':
                        System.out.print("Entry key value to insert: ");
                        aKey = getInt();
                        aDataItem = new Link(aKey);
                        theHashTable.insert(aDataItem);
                        break;
                    case 'd':
                        System.out.print("Enter key value to delete: ");
                        aKey = getInt();
                        theHashTable.delete(aKey);
                        break;
                    case 'f':
                        System.out.print("Enter key value to find: ");
                        aKey = getInt();
                        aDataItem = theHashTable.find(aKey);
                        if (aDataItem !=null){
                            System.out.print("Found " + aKey);
                        }else{
                            System.out.println("could not find " +aKey);
                        }
                        break;
                    default:
                        System.out.print("Invalid entry\n");
                }
            }
        }
    
        public static String getString() throws IOException{
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
            String s = br.readLine();
            return s;
        }
    
        public static char getChar() throws IOException{
            String s = getString();
            return s.charAt(0);
        }
    
        public static int getInt() throws IOException{
            String s = getString();
            return Integer.parseInt(s);
        }
    }
    

     

    展开全文
  • 哈希表的链地址法来解决冲突问题 将所有关键字为同义词的记录存储在同一个线性链表中,假设某哈希函数产生的哈希地址在区间[0, m - 1]上,则设立一个至振兴向量 Chain ChainHash[m]; 数据结构 //链表结点 ...

    哈希表的链地址法来解决冲突问题

    将所有关键字为同义词的记录存储在同一个线性链表中,假设某哈希函数产生的哈希地址在区间[0, m - 1]上,则设立一个至振兴向量

    Chain  ChainHash[m];

     

    数据结构

    //链表结点
    typedef struct _tagNode { int data;              //元素值(关键字)
        struct _tagNode* next; //下一个结点
    }Node, *PNode; //哈希表结点
    typedef struct _tagHashTable { //这里用一个联合体来解释一下,其index也即哈希值
     union{ int index;            //哈希表index(这里也是哈希值)
            int nHashValue;       //也即哈希值
     }INDEX; Node* firstChild;     //该哈希结点在第一个子节点,即哈希值为该结点INDEX字段的
        struct _tagHashTable* next; //指向下一个哈希结点
    }HashTable, *PHashTable;

     

     

     构造哈希表,输入为头结点指针的引用

    //pHashTable 哈希表头结点 //length 哈希表长度 //pArr 关键字元素数组 //nums 关键字元素数组长度
    void CreateHashTable(PHashTable& pHashTable, int length, int* pArr, int nums) { pHashTable = new HashTable(); if(NULL == pHashTable) { cerr << "Create Hashtable error! \n"; return;} pHashTable->firstChild = NULL; pHashTable->INDEX = 0; pHashTable->next = NULL; PHashTable pTemp = pHashTable; for (int i = 1; i < length; ++ i) { PHashTable pt = new HashTable(); if(NULL == pt) {cerr << "Create Hahstable error ! \n"; return;} pt->firstChild = NULL; pt->INDEX = i; pt->next = NULL; pTemp->next = pt; pTemp = pt; } //for //Hash(key) = key MOD length;
        for(int i = 0; i < nums; ++ i) { //计算哈希值
            int nHashValue = pArr[i] % length; PHashTable pTemp2 = NULL; if(NULL != (pTemp2 = LocateHashNode(pHashTable, nHashValue)) ) { Insert(pTemp2, pArr[i]); } else { cerr << "元素值为 "<< pArr[i]<< " 的元素,哈希值为 "<< nHashValue<< ", 查找其所在哈希结点失败"<<endl; } } }

     

     

     

     向某个哈希表结点(不一定是头结点)中插入元素

    //将关键字插入所在的pHashtable结点的链表 //返回其在该链表上的位置(下标从1开始)
    int Insert(PHashTable& pHashtable, int data) { if(NULL == pHashtable){cerr << "当前哈希表结点为空 \r\n"; return -1;} int nIndex = 1; PNode pNewNode = new Node(); if(NULL == pNewNode){cerr << "建立新链表结点失败"<<endl; return -1;} pNewNode->data = data; pNewNode->next = NULL; PNode pNode = pHashtable->firstChild; if (NULL == pNode) { pHashtable->firstChild = pNewNode; } else { while(pNode->next != NULL) { ++ nIndex; pNode = pNode->next; } ++nIndex; pNode->next = pNewNode; } cout << "元素 "<< data << " 插入在了哈希表结点 "<< pHashtable->INDEX<< " 的第 "<< nIndex<< " 个位置"<<endl; return nIndex; }

     

     

     

     根据哈希值,返回其所在结点的指针,输入为表示该哈希表的头结点指针的引用

    //根据哈希值,返回该值应该所在的哈希表结点指针 //pHashtable 哈希表头结点 //nHashValue 元素的哈希值
    PHashTable LocateHashNode(PHashTable& pHashtable, int nHashValue) { if(NULL == pHashtable) {cerr << "哈希表头结点为空"<<endl; return NULL;} PHashTable pTemp = pHashtable; do { if (pTemp->INDEX == nHashValue) return pTemp; pTemp = pTemp->next; } while (pTemp != NULL); return NULL; }

     

     

     

     从头结点为pHashtable的哈希表中,查找关键字为data,哈希值为nHashValue的元素

    在哈希表中的位置,返回值为在该哈希结点的链表中的位置(下标从1开始)

        
    //查找头结点为pHashtable的哈希表 //其数据为data,哈希值为nHashValue的元素 //在哈希表某个结点的链表中的位置(下标从1开始)
    int Find(PHashTable& pHashtable, int data, int nHashValue) { if(NULL == pHashtable){cerr << "哈希表头结点为空"<<endl; return -1;} PHashTable pHashNode = LocateHashNode(pHashtable, nHashValue); if(NULL == pHashNode) {cerr << "找不到元素 " << data << " ,其哈希值为 "<<nHashValue<< " 在哈希表中的位置"; return -1;} int nINDEX = 1; PNode pNode = pHashNode->firstChild; if (NULL == pNode) { {cerr << "找不到元素 " << data << " ,其哈希值为 "<<nHashValue<< " 在哈希表中的位置"; return -1;} } else { bool b = false; while(pNode != NULL) { if(pNode->data == data) { b = true; break; } ++ nINDEX; pNode = pNode->next; } if (false == b) { cerr << "找不到元素 " << data << " ,其哈希值为 "<<nHashValue<< " 在哈希表中的位置"; return -1; } else { cout << "元素 "<< data << " 插入在了哈希表结点 "<< pHashNode->INDEX<< " 的第 "<< nINDEX<< " 个位置"<<endl; } } return nINDEX; }

     

      

     

    int _tmain(int argc, _TCHAR* argv[]) { PHashTable pHashtable = NULL; int length = 0; int nums = 0; cout <<endl<< "请输入元素个数:"; cin >> nums; int* pArr = new int[nums](); if(NULL == pArr) {cerr<<"申请元素空间错误"; return -1;} ZeroMemory(pArr, sizeof(int) * nums); for (int i = 0; i < nums; ++ i) { int data = 0; cout << "请输入第 "<< i << " 个元素的值:"; cin >> data; pArr[i] = data; } cout << endl<<"输入完毕"<<endl; cout << "请输入哈希表长度:"; cin >> length; cout << endl <<endl <<"开始构造哈希表"<<endl; CreateHashTable(pHashtable, length, pArr, nums); cout <<endl<<"哈希表构造完毕"<<endl<<endl; cout<<endl<<endl; int value = 0; for (int i = 0; i < nums * 10; ++ i) { cout << "请输入要查查找的元素:"; cin >> value; Find(pHashtable, value, value % length); cout<<endl; } return 0; }

     

     

     

     

     

     

     

     

      

    转载于:https://my.oschina.net/u/926461/blog/350879

    展开全文
  • Hash (链地址法处理冲突) Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值...

    Hash (链地址法处理冲突)

    Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。(百度百科)

    HashTable通过key来查找信息,极大提高了时间效率,但不同的信息可能拥有相同的key值,这就是冲突,这里用链地址法来解决冲突,即有冲突的信息具有相同的key值,将它们按顺序链接在同一地址下(尾插法)。
    来源于百度
    (百度图片)

    这里还有:Hash 哈希表 (开放地址法解决冲突)

    代码如下:

    in:
    13
    13
    16 74 60 43 54 90 46 31 29 88 77 78 79
    16
    out:
    3,1
    
    #include"bits/stdc++.h"
    using namespace std;
    
    #define MAX 24
    #define INIFINITE 201201//定义无限大 
    typedef char DataType;//定义数据类型 
    typedef int KeyType;//定义关键字类型 
    typedef struct node{
    	int key;//储存关键字信息 
    	struct node *next; 
    }HashListNode; 
    typedef struct{
    	DataType data; 
    	KeyType key;
    	HashListNode *firstare;//指向的第一片区域 
    }HashTable[MAX],Hash;
    
    int H(int key,int n){//除留余数 
    	return key%n;
    }
    void Init(Hash test[],int n){//初始化 
    	for(int i=0;i<n;i++){
    		test[i].key=INIFINITE;
    		test[i].firstare=NULL;//注意这的初始化 
    	}
    }
    void CreatHashList(HashListNode *&link,int key){//创建链地址 (尾插法) 
    	HashListNode *p;
    	p=new HashListNode;
    	p->key=key;
    	p->next=NULL;
    	if(!link){
    		link=p;
    	}
    	else{
    		while(link->next){
    			
    			link=link->next;
    		}
    		link->next=p;
    	}
    		
    }
    void CreateHash(Hash test[],int num,int n){//创建哈希表 
    	bool flag[MAX]={false};//冲突标记 
    	for(int i=0;i<num;i++){
    		int temp,k;
    		cin>>temp;//关键字信息 
    		k=H(temp,n);
    		if(!flag[k]){//若未冲突 
    			test[k].key=temp;
    			flag[k]=true; 
    		}
    		else{//处理冲突 
    			CreatHashList(test[k].firstare,temp);
    		}
    	}
    } 
    void SearchNode(Hash test[],int n){//查找结点,查找失败输出-1
    	int aim,count=0;
    	cin>>aim;//目标 
    	int k=H(aim,n);
    	bool flag=false;//查找到的标记 
    	if(test[k].key==INIFINITE){
    		cout<<"-1";
    		return;
    	}
    	
    	if(test[k].key==aim){
    		flag=true;
    		count++;
    	}
    	else{
    		count++;//下面直接从下一片区域找起  这要加一次   
    		while(test[k].firstare){
    			count++;
    			if(test[k].firstare->key==aim){
    				flag=true;
    				break;
    			}
    			test[k].firstare=test[k].firstare->next;
    		}
    	}
    	if(!count||!flag){
    		cout<<"-1";
    	}
    	else{
    		cout<<k<<","<<count;
    	}
    	
    }
    int main(){
    	HashTable test;
    	int n,num;
    	cin>>n>>num;
    	Init(test,n);
    	CreateHash(test,num,n);
    	SearchNode(test,n);
    	
    	return 0;
    }
    
    

    请多指教

    展开全文
  • 一、链地址法 散列表基础介绍与散列冲突见文章:https://blog.csdn.net/qq_41453285/article/details/103517420 链地址法的基本思想:在散列表的每一个位置分配一个线性表。这样,每一个数对就可以存储在它的起始...

    一、链地址法

    • 散列表基础介绍与散列冲突见文章:https://blog.csdn.net/qq_41453285/article/details/103517420
    • 链地址法的基本思想:在散列表的每一个位置分配一个线性表。这样,每一个数对就可以存储在它的起始桶线性表中了
    • 链地址法同时也解决了散列表移除的问题
    • 例如,下图就是一个散列表,其中产生散列冲突的元素存储在同一个桶链表中了

    二、链地址法的增加、删除、查找

    查找

    • 根据关键字k与散列函数f(k)=k%D,计算起始桶。然后搜索该桶对应的链表

    增加:

    • 首先保证散列表没有一个记录与该记录的关键字相同,为此而进行的搜索仅限于该记录的起始桶所对应的链表

    删除:

    • 删除一个关键字为k的记录,先搜索它所对应的起始桶链表,找到该记录然后删除

    三、一种改进的实现方法

    • 在每个链表上增加一个尾节点,可以改进一些程序的性能
    • 尾节点的关键字值最起码要比插入的所有数对的关键字都大
    • 有了尾节点就省去了在链表中出现的大部分对空指针的检验操作
    • 备注:每个链表都有不同的尾节点,实际上,所有的链表可共用一个尾节点
    • 例如在下图中,尾节点的关键字用表示(实际中用整数表示),可以使用limits.h头文件中定义的INT_MAX来替代

     

    四、与线性探查法的比较

    五、与跳表的比较

    六、编码实现1

    • 我们在前面用链表实现过字典(sortedChain),因为链地址法中散列表的每一个位置都是一个链表,因此我们可以直接定义一个类,在类中使用前面文章介绍过的sortedChain来实现链地址法
    • sortedChain实现见文章:https://blog.csdn.net/qq_41453285/article/details/103449056

    头文件定义 

    #include <iostream>
    #include <string>
    #include <utility>
    
    using std::cout;
    using std::cin;
    using std::endl;
    using std::pair;
    using std::string;

    hash类定义

    • 用于将关键字映射为一个整数,便于在散列中进行操作
    template<class K> class hash;
    
    template<>
    class hash<std::string>
    {
    public:
    	std::size_t operator()(const std::string theKey)const
    	{
    		unsigned long hashValue = 0;
    		int length = (int)theKey.length();
    		for (int i = 0; i < length; i++) {
    			hashValue = hashValue * 5 + theKey.at(i);
    		}
    
    		return std::size_t(hashValue);
    	}
    };
    
    template<>
    class hash<int>
    {
    public:
    	std::size_t operator()(const int theKey) const
    	{
    		return std::size_t(theKey);
    	}
    };
    
    template<>
    class hash<long>
    {
    public:
    	std::size_t operator()(const long theKey) const
    	{
    		return std::size_t(theKey);
    	}
    };

    字典链表定义

    • 链地址法中,散列表的每一个位置都是一个链表,链表就使用下面的sortedChain表示
    template<class K,class E>
    struct pairNode
    {
    	typedef std::pair<const K, E> pairType;
    
    	pairType element;
    	struct pairNode<K,E>* next;
    
    	pairNode(const pairType& thePair):element(thePair) {}
    	pairNode(const pairType& thePair, struct pairNode<K, E>* theNext) :element(thePair) { this->next = theNext; }
    };
    
    
    template<class K, class E>
    class sortedChain :public dictionary<K, E>
    {
    public:
    	sortedChain();
    	~sortedChain();
    	bool empty()const override;
    	int size()const override;
    	std::pair<const K, E>* find(const K& theKey)const override;
    	void erase(const K& theKey) override;
    	void insert(const std::pair<const K, E>& thePair) override;
    
    	void output(std::ostream &out)const;
    private:
    	pairNode<K, E>* firstNode;
    	int dSize;
    };
    
    template<class K, class E>
    sortedChain<K, E>::sortedChain()
    {
    	this->firstNode = nullptr;
    	this->dSize = 0;
    }
    
    template<class K, class E>
    sortedChain<K, E>::~sortedChain()
    {
    	pairNode<K, E>* tempNode;
    	while (this->firstNode) {
    		tempNode = this->firstNode->next;
    		delete this->firstNode;
    		this->firstNode = tempNode;
    	}
    }
    
    template<class K, class E>
    bool sortedChain<K, E>::empty()const
    {
    	return this->dSize == 0;
    }
    
    template<class K, class E>
    int sortedChain<K, E>::size()const
    {
    	return this->dSize;
    }
    
    template<class K, class E>
    std::pair<const K, E>* sortedChain<K, E>::find(const K& theKey)const
    {
    	pairNode<K, E>* tempNode = this->firstNode;
    
    	//遍历字典
    	while ((tempNode != nullptr) && (tempNode->element.first != theKey))
    		tempNode = tempNode->next;
    
    	//如果找到了就返回
    	if ((tempNode != nullptr) && (tempNode->element.first == theKey))
    		return &tempNode->element;
    
    	//没有找到就返回空
    	return nullptr;
    }
    
    template<class K, class E>
    void sortedChain<K, E>::erase(const K& theKey)
    {
    	pairNode<K, E>* eraseNode = this->firstNode;
    	pairNode<K, E>* beforeEraseNode = nullptr;
    
    	//遍历字典
    	while ((eraseNode != nullptr) && (eraseNode->element.first < theKey))
    	{
    		beforeEraseNode = eraseNode;
    		eraseNode = eraseNode->next;
    	}
    
    	//找到了就删除
    	if ((eraseNode != nullptr) && (eraseNode->element.first == theKey))
    	{
    		//如果删除的是头结点
    		if (eraseNode == this->firstNode) {
    			this->firstNode = eraseNode->next;
    		}
    		else {
    			beforeEraseNode->next = eraseNode->next;
    		}
    		delete eraseNode;
    		this->dSize--;
    	}
    }
    
    template<class K, class E>
    void sortedChain<K, E>::insert(const std::pair<const K, E>& thePair)
    {
    	pairNode<K, E>* afterInsertNode = this->firstNode;
    	pairNode<K, E>* beforeInsertNode = nullptr;
    
    	//遍历字典
    	while ((afterInsertNode != nullptr) && (afterInsertNode->element.first < thePair.first))
    	{
    		beforeInsertNode = afterInsertNode;
    		afterInsertNode = afterInsertNode->next;
    	}
    
    	//如果键已经存在,更新值
    	if ((afterInsertNode != nullptr) && (afterInsertNode->element.first == thePair.first))
    	{
    		afterInsertNode->element.second = thePair.second;
    		return;
    	}
    
    	//如果键不存在,插入新节点
    	pairNode<K, E>* insertNode = new pairNode<K, E>(thePair, afterInsertNode);
    	if (beforeInsertNode == nullptr)
    		this->firstNode = insertNode;
    	else
    		beforeInsertNode->next = insertNode;
    	this->dSize++;
    }
    
    template<class K, class E>
    void sortedChain<K, E>::output(std::ostream &out)const
    {
    	for (pairNode<K, E>* tempNode = this->firstNode; tempNode != nullptr; tempNode = tempNode->next) {
    		out << "key:" << tempNode->element.first << ",value:" << tempNode->element.second << std::endl;
    	}
    }
    
    template<class K,class E>
    std::ostream& operator<<(std::ostream& out,const sortedChain<K,E>& theChain)
    {
    	theChain.output(out);
    	return out;
    }

    散列表的最终实现 

    template<class K,class E>
    class dictionary
    {
    public:
    	virtual ~dictionary(){}
    	virtual bool empty()const = 0;
    	virtual int size()const = 0;
    	virtual std::pair<const K, E>* find(const K& theKey)const = 0;
    	virtual void erase(const K& theKey) = 0;
    	virtual void insert(const std::pair<const K, E>& thePair) = 0;
    };
    
    template<class K,class E>
    class hashChains :public dictionary<K, E>
    {
    public:
    	hashChains(int theDivisor=11);
    	~hashChains();
    	bool empty()const override;
    	int size()const override;
    	std::pair<const K, E>* find(const K& theKey)const override;
    	void erase(const K& theKey) override;
    	void insert(const std::pair<const K, E>& thePair) override;
    
    	void output(std::ostream & out)const;
    private:
    	sortedChain<K, E>* table;
    	hash<K> hash;  //将关键字映射为一个整数
    	int dSize;     //哈希表的大小
    	int divisor;   //哈希函数的除数
    };
    
    template<class K, class E>
    hashChains<K, E>::hashChains(int theDivisor = 11)
    {
    	this->divisor = theDivisor;
    	this->dSize = 0;
    
    	this->table = new sortedChain<K, E>[theDivisor];
    }
    
    template<class K, class E>
    hashChains<K, E>::~hashChains()
    {
    	if (this->table) {
    		delete[] this->table;
    		this->table = nullptr;
    	}
    }
    
    template<class K, class E>
    bool hashChains<K, E>::empty()const
    {
    	return (this->dSize == 0);
    }
    
    template<class K, class E>
    int hashChains<K, E>::size()const
    {
    	return this->dSize;
    }
    
    template<class K, class E>
    std::pair<const K, E>* hashChains<K, E>::find(const K& theKey)const
    {
    	int index = hash(theKey) % this->divisor;
    	return this->table[index].find(theKey);
    }
    
    template<class K, class E>
    void hashChains<K, E>::erase(const K& theKey)
    {
    	int index = hash(theKey) % this->divisor;
    	this->table[index].erase(theKey);
    }
    
    template<class K, class E>
    void hashChains<K, E>::insert(const std::pair<const K, E>& thePair)
    {
    	int bucketIndex = hash(thePair.first) % this->divisor;
    	int homeSize = this->table[bucketIndex].size();
    	this->table[bucketIndex].insert(thePair);
    
    	//如果insert操作不是替换值,而是插入新值,那么就增加元素个数
    	if (this->table[bucketIndex].size() > this->dSize) {
    		this->dSize++;
    	}
    }
    
    template<class K, class E>
    void hashChains<K, E>::output(std::ostream & out)const
    {
    	for (int i = 0; i < this->divisor; ++i) {
    		if (this->table[i].empty())
    			std::cout << "NULL" << std::endl;
    		else
    			std::cout << this->table[i];
    	}
    }
    
    template<class K,class E>
    std::ostream& operator<<(std::ostream &out,const hashChains<K,E>& theHashChains)
    {
    	theHashChains.output(out);
    	return out;
    }

    主函数

    int main()
    {
    	hashChains<int, int>* myHashChains = new hashChains<int, int>(11);
    	
    	myHashChains->insert(std::pair<int, int>(1, 1));
    	myHashChains->insert(std::pair<int, int>(2, 2));
    	myHashChains->insert(std::pair<int, int>(3, 3));
    
    	std::cout << myHashChains;
    
    	return 0;
    }

    七、编码实现2

    • 待续
    展开全文
  • 拉链解决冲突的做法是:将所有关键字为同义词的结点链接在同一个单链表中。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数组T[0..m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的...
  • 输入一组关键字,并建立哈希表的算法(用链地址法来处理冲突
  • 哈希表-链地址法

    千次阅读 2009-03-31 15:33:00
    import java.io.IOException; import java.io.InputStreamReader;... * @Description 哈希表发生冲突时的链地址方法算法,关键字通过哈希函数映射到哈希表单元,而插入时插入到这个单元的链表中  *
  • 输入一组关键字并建造哈希表的算法,用链地址法处理冲突
  • 初学者学习哈希表可以看看
  • 建立n元关键字哈希表,用链地址法解决冲突,输出建立的哈希表。(按链表的顺序),输入任意元素实现查找查找结果分成功和失败,要求查找时可以反复输入关键字查找,直至输入停止标识符时程序结束。 二.输入与输出...
  • 【查找算法哈希查找

    千次阅读 2020-02-26 12:44:45
    散列表冲突构造散列函数直接定址法除留余数法解决冲突的方式开放地址法链地址法 何为哈希查找? 先看定义: 哈希查找是通过计算数据元素的存储地址进行查找的一种方法。 哈希查找通过给定的哈希函数构造哈希表(也...
  • 哈希冲突

    万次阅读 2019-06-09 21:12:41
    问题一、什么是哈希冲突 由于哈希算法被计算的数据是无限的,而计算后的结果范围有限,因此总会存在不同的数据经过计算后得到的...2、链地址法(拉链法) 3、再哈希法 4、创建公共溢出区 详细解释: 1、开放地...
  • Redis哈希冲突问题

    2020-04-05 17:45:45
    哈希算法 在Redis的字典中,当要将一个新的键值对添加...Redis哈希表采用链地址法解决键冲突,每个哈希表的节点会有next指针,被分到同一个位置的键值对节点就会使用单链表连接起来。 如图: rehash 哈希表保存的...
  • 链地址法处理Hash冲突

    2012-10-29 08:47:42
    链地址法处理Hash冲突 博客分类: 查找 java 数据结构 算法   哈希表中的每个位置称为桶(bucket),当发生哈希冲突时就以链表形式存放多个元素。 链地址法处理Hash冲突,看看下面代码...
  • 算法比赛中,经常会用到hash来处理快速搜索和... (2 ) 解决冲突采用链地址法。 数据举例: 需要被hash的数据列表为(19,14,23,01,68,20,84,27,55,11,10,79),取哈希函数为H(key)=key MOD 13。则预想结果应为:
  • 哈希算法: 比较 常见的数据查找算法,如顺序查找(最简单,效率低),二分查找(效率高,要求数据有序),深度优先广度优先搜索(对于大...链地址法,有N个哈希地址就有N个链表,数组Hash存放每个链表头指针 下...
  • 一、开放定址:开放定址是一类以发生冲突哈希地址为自变量,通过某种哈希冲突函数得到一个新的空闲地址的方法。 在开放定址中常用的有线性探查和平探查;线性探查容易产生堆积问题。而平方探查可以...
  • 解决哈希冲突的方法

    2021-06-02 18:03:38
    哈希表我们平时用的很多,比如map结构中,...此处通过链地址法来解决哈希冲突问题。 思路就是,如果多个key落在了同一个下标的话,就将其转换成单向链表。 这样,就需要遍历此单向链表来得到某个key对于的val。 ...
  • 来看一道题,问HashMap是用下列哪种方法来解决哈希冲突的? A 开放地址法 B 二次哈希法 C 链地址法 D 建立一个公共溢出区 答案是:C 解决哈希冲突的方法有三种,分别... 链地址法(拉链法):将所有冲突元素按照链表存储...
  • 文章目录相关概念及说明一、开放地址法(1)、线性探测再散列(2)、二次探测再散列(3)、伪随机再散列二、链地址法三、再散列法四、公共溢出区 相关概念及说明 哈希冲突: 由于哈希算法被计算的数据是无限的,而计算后...
  • 例如:字符串、单词个数的统计,只出现一次字符或者数字的统计,两个集合相同元素的查找等等,还有插入删除的高效(链地址法)都可以用哈希表来解决。所以这里对其做一个小小的总结。缺点可能是需要占用额外的内存...
  • /*  ... * All rights reserved.... * 文件名称:a * 作 者:张翠平  ...* 问题描述:设计算法,输出哈希表,并计算成功情况和不成功情况下的平均查找长度。 * 输入描述: * 程序输出:输出哈希表,并计算成功
  • 算法哈希

    2021-06-02 21:29:36
    哈希表1 基本思想2 解决冲突2.1 分离链接开放定址2.2 线性探测2.3 平方探测2.4 双散列2.5 再散列 1 基本思想 选择散列函数,解决冲突。 2 解决冲突 2.1 分离链接 散列到同一个值得所有元素保留到一个链表中。 ...
  • 文章目录数组和链表的特点哈希哈希函数解决哈希冲突链地址法开放地址法 数组和链表的特点 数组支持随机存取; 分配数组需要连续的内存空间; 链表不支持随机存取; 链表不需要连续的内存空间; 哈希表 由于数组和...
  • 算法与数据结构的一个题目,用链地址法和开放定址法,求等概率情况下查找成功时的平均查找长度 已知一组关键字(13,20,85,52,8),哈希函数为:H(key)=key MOD 6 1)用开放定址法处理冲突,选用线性探测再散列处理冲突...
  • 链地址法 将所有Hash地址相同的记录都链接在同一链表中 再Hash法 同时构造多个不同的Hash函数,当产生冲突时,计算另一个Hash函数地址直到不再发生冲突为止。 建立公共溢出区 将Hash表分为基本表和溢出表,若是与基本表...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 153
精华内容 61
关键字:

哈希算法冲突链地址法