散列存储(开放地址法-双重散列)

散列存储(双重散列)

 

 

双重散列采用如下形式的散列函数:

H(k,i) = ( h1(k) +i*h2(k) ) mod m

 

H2(k)必须与表的大小M互为素数!!

 

方法:

1) 取M为2的幂,并设计一个总产生奇数的h2

2) 取M为素数,并设计一个总是返回较m小的正整数的函数h2

 

h1(k) = k mod m

h2(k) = 1+ ( k mod m’)

 

 

代码:

 

#include<stdio.h>

#include<assert.h>

#include<math.h>

#include<stdlib.h>

#include<iostream>

 

using namespace std;

 

#define SUCCESS 1

#define UNSUCCESS 0

#define HASHBIAOSIZE  15 //决定散列表大小的参数

#define M 11      //这里要取素数!!!

#define NULLKEY -65535

#define Hash(v) (v % 9)       //h1(k)

#define Hash2(v) ((v % 7) + 1)   // h2(k)

//----------------------------------------------------------------------------//

typedef struct  HashTable

{

   int* element;//

   int count;//

} HashTable;

 

int m=0;

void InitHashTable(HashTable *H);

void InsertHashKey(HashTable* H,int key);

int  Hash_f(int key);

int HashTabelSearch(HashTable* H,int key);

//----------------------------------------------------------------------------//

 

int main()

{

   int a[]= {1,12,5,4,6,8,7,45,21,13,18};

HashTable H;

 

//初始化!!

InitHashTable(&H);

 

   for(int i=0; i<M; i++){

       InsertHashKey(&H,a[i]);

    }

 

   for(int j=0; j<M; j++)

    {

       if(HashTabelSearch(&H,a[j]) == -1)

           printf("没查找到\n");

       else

           printf("查找元素%d存储的标号%d\n",a[j],HashTabelSearch(&H,a[j]));

    }

 

   return 0;

}

 

//----------------------------------------------------------------------------//

void InitHashTable(HashTable *H)

{

   m=HASHBIAOSIZE;

   H->element=(int*)malloc(m*sizeof(int));

   H->count=HASHBIAOSIZE;

 

   for(int i=0; i<m; i++)

    {

       H->element[i]=NULLKEY;

    }

}

//----------------------------------------------------------------------------//

//存储元素

//这里采用取余数法

void InsertHashKey(HashTable* H,int key){

 

   int addr=Hash_f(key);

   while(H->element[addr]!=NULLKEY){ //冲突了

      addr=(addr+1)%M;//解决冲突

    }

   H->element[addr]=key;

 

}

//----------------------------------------------------------------------------//

//查找元素

 

int HashTabelSearch(HashTable* H,int key)

{

   int hash_key = Hash(key);

   int hash_key2 = Hash2(key);

   int temp = 0;

 

   while (H->element[hash_key] != NULLKEY) {

       if( H->element[hash_key] == key )

           break;

       temp = hash_key;

       hash_key = (hash_key+hash_key2) % M;

 

//这里是检验会不会出现怎么加都不会变的情况,不过一般不会有!

        if( hash_key == temp )

           return -1;

    }

   return hash_key;

}

//----------------------------------------------------------------------------//

int Hash_f(int key){

   return key%M;

}

//----------------------------------------------------------------------------//

 


 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,这是一个关于C++实现哈希表的问题。下面是分别采用链表开放地址(双重)方存储随机数,并实现相关的查询、插入和删除等基本操作的代码示例: 链表: ```c++ #include<iostream> #include<cstdlib> using namespace std; //定义哈希表节点 struct HashNode { int data; HashNode* next; HashNode() :data(0), next(nullptr) {} }; //定义哈希表 class HashTable { public: HashTable(int size); ~HashTable(); int HashFunc(int key); void Insert(int key); void Delete(int key); bool Search(int key); void ShowTable(); private: int m_size; HashNode* m_table; }; //哈希表构造函数 HashTable::HashTable(int size) { m_size = size; m_table = new HashNode[m_size]; } //哈希表析构函数 HashTable::~HashTable() { for (int i = 0; i < m_size; i++) { HashNode* p = m_table[i].next; while (p != nullptr) { HashNode* q = p->next; delete p; p = q; } } delete[] m_table; } //哈希函数 int HashTable::HashFunc(int key) { return key % m_size; } //插入操作 void HashTable::Insert(int key) { int index = HashFunc(key); HashNode* p = new HashNode; p->data = key; p->next = m_table[index].next; m_table[index].next = p; } //删除操作 void HashTable::Delete(int key) { int index = HashFunc(key); HashNode* p = &m_table[index]; while (p->next != nullptr && p->next->data != key) p = p->next; if (p->next == nullptr) cout << "没有找到要删除的元素!" << endl; else { HashNode* q = p->next; p->next = q->next; delete q; } } //查找操作 bool HashTable::Search(int key) { int index = HashFunc(key); HashNode* p = m_table[index].next; while (p != nullptr && p->data != key) p = p->next; if (p == nullptr) return false; else return true; } //显示哈希表 void HashTable::ShowTable() { for (int i = 0; i < m_size; i++) { HashNode* p = m_table[i].next; cout << i << ": "; while (p != nullptr) { cout << p->data << " "; p = p->next; } cout << endl; } } int main() { HashTable hashTable(10); srand((unsigned)time(NULL)); for (int i = 0; i < 10; i++) hashTable.Insert(rand() % 20); hashTable.ShowTable(); cout << "请输入要删除的元素:"; int key; cin >> key; hashTable.Delete(key); hashTable.ShowTable(); cout << "请输入要查找的元素:"; cin >> key; if (hashTable.Search(key)) cout << "找到了要查找的元素!" << endl; else cout << "没有找到要查找的元素!" << endl; return 0; } ``` 开放地址(双重): ```c++ #include<iostream> #include<cstdlib> using namespace std; //定义哈希表节点 struct HashNode { int key; HashNode() :key(-1) {} }; //定义哈希表 class HashTable { public: HashTable(int size); ~HashTable(); int HashFunc1(int key); int HashFunc2(int key); void Insert(int key); void Delete(int key); bool Search(int key); void ShowTable(); private: int m_size; HashNode* m_table; }; //哈希表构造函数 HashTable::HashTable(int size) { m_size = size; m_table = new HashNode[m_size]; } //哈希表析构函数 HashTable::~HashTable() { delete[] m_table; } //哈希函数1 int HashTable::HashFunc1(int key) { return key % m_size; } //哈希函数2 int HashTable::HashFunc2(int key) { return 3 - key % 3; } //插入操作 void HashTable::Insert(int key) { int index = HashFunc1(key); int step = HashFunc2(key); while (m_table[index].key != -1) { index = (index + step) % m_size; } m_table[index].key = key; } //删除操作 void HashTable::Delete(int key) { int index = HashFunc1(key); int step = HashFunc2(key); while (m_table[index].key != -1 && m_table[index].key != key) { index = (index + step) % m_size; } if (m_table[index].key == -1) cout << "没有找到要删除的元素!" << endl; else m_table[index].key = -1; } //查找操作 bool HashTable::Search(int key) { int index = HashFunc1(key); int step = HashFunc2(key); while (m_table[index].key != -1 && m_table[index].key != key) { index = (index + step) % m_size; } if (m_table[index].key == -1) return false; else return true; } //显示哈希表 void HashTable::ShowTable() { for (int i = 0; i < m_size; i++) { cout << i << ": " << m_table[i].key << endl; } } int main() { HashTable hashTable(10); srand((unsigned)time(NULL)); for (int i = 0; i < 10; i++) hashTable.Insert(rand() % 20); hashTable.ShowTable(); cout << "请输入要删除的元素:"; int key; cin >> key; hashTable.Delete(key); hashTable.ShowTable(); cout << "请输入要查找的元素:"; cin >> key; if (hashTable.Search(key)) cout << "找到了要查找的元素!" << endl; else cout << "没有找到要查找的元素!" << endl; return 0; } ``` 以上两个示例代码实现了哈希表的基本操作,可以根据自己的需要进行调整和扩展。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值