哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现

#include<iostream>
#include<iomanip>
using namespace std;

typedef struct Node
{
 int data;
 struct Node *next;
}node;

int len,num,M,numbers,i=0,mod,count=0;
int *a;
node **p,*s;
float ASL=0,ASL1=0;

int ListLength(node * head)
{
 int length=0;
 node *p;
 p=head;
 while(p)
 {
  length++;
  p=p->next;
 }
 return length;
}

void Insert(node * &head,node * s)
{
 node *p;
 p=head;
 while(p->next)
 {
  p=p->next;
 }
 p->next=s;
}

void Print(node * head)
{
 node *p;
 p=head;
 while(p)
 {
  cout<<"->"<<p->data;
  p=p->next;
 }
}

void f1()
{
 cout<<"Input HashTable address length:";
 cin>>len;
 cout<<"Input the value of M in Hash function H(k)=k%M:";
 cin>>M;
 a=new int[len];
 cout<<"Input the number of data to be hashed into the hash table:";
 cin>>numbers;
 for(i=0;i<len;i++)
 {
  a[i]=-1;
 }
    cout<<"please input the keys:";
    for(i=1;i<=numbers;i++)
 {
  cin>>num;
  mod=num%M;
  if(a[mod]==-1)
  {
  a[mod]=num;
  ASL+=1;
  }
  else
  {
   while(a[(++mod)%len]!=-1)
   {
    count++;
   }
   a[mod]=num;
   ASL+=(count+2);
  }
 }

for(i=0;i<len;i++)
 {
  count=0;
  if(a[i]==-1)
   ASL1+=0;
  else
  {
   int j=i;
   while(a[(++j)%len]!=-1)
   {
    count++;
   }
   ASL1+=(count+1);
  }
 }
 cout<<"the hash table is as followed:"<<endl<<endl;
 cout<<"HashAddress";
 for(i=0;i<len;i++)
 {
  cout<<setw(4)<<i;
 }
 cout<<endl;
 cout<<"    Key    ";
 for(i=0;i<len;i++)
 {
  if(a[i]==-1)
   cout<<setw(4)<<‘\0‘;
  else
      cout<<setw(4)<<a[i];
 }
 cout<<endl<<endl;
 cout<<"Hash search successfully using linear detection method to resolve conflicts and the average search length ASL is:";
 cout<<(float)ASL/numbers<<endl;
 cout<<"Hash search unsuccessfully using linear detection method to resolve conflicts and the average search length ASL is:";
 cout<<(float)ASL1/len<<endl;
}

void f2()
{
 cout<<"input HashTable address length:";
 cin>>len;
 p=new node*[len];
 cout<<"Input the value of M in Hash function H(k)=k%M:";
 cin>>M;
 cout<<"Input the number of key to be hashed into the hash table:";
 cin>>numbers;
 for(i=0;i<len;i++)
 {
  p[i]=NULL;
 }
 cout<<"please input the keys:";
 for(i=0;i<numbers;i++)
 {
  cin>>num;
  mod=num%M;
  if(p[mod]==NULL)
  {
   p[mod]=new node;
   p[mod]->data=num;
   p[mod]->next=NULL;
   ASL+=1;
  }
  else
  {
   s=new node;
   s->data=num;
   s->next=NULL;
   Insert(p[mod],s);
   ASL+=ListLength(p[mod]);
  }
 }
 for(i=0;i<len;i++)
 {
  if(p[i]==NULL)
   ASL1+=0;
  else
   ASL1+=ListLength(p[i]);
 }
 cout<<"the hash table is as followed:"<<endl<<endl;
 for(i=0;i<len;i++)
 {
  cout<<setiosflags(ios::left)<<setw(3)<<i;
  if(p[i]==NULL)
   cout<<‘^‘<<endl;
  else
  {
   Print(p[i]);
   cout<<endl;
  }
 }
 cout<<endl;   
 cout<<"Hash search successfully using chain address method to resolve conflicts and the average search length ASL is:";
 cout<<(float)ASL/numbers<<endl;
 cout<<"Hash search unsuccessfully using chain address method to resolve conflicts and the average search length ASL is:";
 cout<<(float)ASL1/len<<endl;
}

void main()
{
    int choice;
 cout<<"1.Linear detection and re hash "<<endl;
 cout<<"2.separate chaining "<<endl;
 cout<<"please choose a method to solve the address conflict:";
 cin>>choice;
 system("cls");
 switch(choice)
 {
 case 1:f1();break;
 case 2:f2();break;
 default:cout<<"input error!"<<endl;break;
 }
}

原文地址:https://www.cnblogs.com/lyj-blogs/p/HashSearchByLyj.html

时间: 2024-10-24 09:02:42

哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现的相关文章

哈希表---线性探测再散列(hash)

//哈希表---线性探测再散列 #include <iostream> #include <string> #include <stdio.h> #include <string.h> #define m 10000 #define NULLkey -1 using namespace std; int HashTable[m]; int Hash_search( int k) { int p0, pi; p0=hash(k); //函数运算值 if(Has

DS哈希查找—二次探测再散列

题目描述 定义哈希函数为H(key) = key%11.输入表长(大于.等于11),输入关键字集合,用二次探测再散列构建哈希表,并查找给定关键字. 输入 测试次数t 每组测试数据格式如下: 哈希表长m.关键字个数n n个关键字 查找次数k k个待查关键字 输出 对每组测试数据,输出以下信息: 构造的哈希表信息,数组中没有关键字的位置输出NULL 对k个待查关键字,分别输出: 0或1(0—不成功,1—成功).比较次数.查找成功的位置(从1开始) 样例输入 1 12 10 22 19 21 8 9

JavaScript解决命名冲突的一种方法

过程化编码 过程化编码, 表现为 定义若干函数,然后调用定义函数, 随着页面交互逻辑变化, 从简单到复杂, 定义的所有函数.和变量 都挂在 window对象上, window对象 编程者子自定义变量名称 规模会愈来愈额庞大,在后面开发和维护的过程中, 很容易导致函数名称冲突,引起意想不到问题. 例如, 之前有个同事定义了 一个 sample 函数, N长时间后, 另一个同事又定义了一个含义不同的同名函数sample,则前以同事的代码就有问题了. 模块化方法一则 JS函数内部相当于一个小的程序空间

Jmeter 的两种脚本录制方法

Jmeter 的两种脚本录制方法有一.通过badboy工具录制:二.通过Jmeter代理录制 一.通过badboy工具录制 1).工具下载地址:www.badboy.com.au/ 2).下载安装完成后,打开工具(工具默认开启录制),在地址栏输入被测项目的地址,点击右侧箭头即可录制 3).录制完成后,点击结束按钮,选择File--Export Jmeter ,最后的文件格式为.jmx类型 4).打开Jmeter工具,选择文件--打开,选择上一步保存的文件,文件即可成功导入进Jmeter 5).练

Android两种旋转Bitmap方法比较

方法1. 利用Bitmap.createBitmap Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) { Matrix m = new Matrix(); m.setRotate(orientationDegree, ( float ) bm.getWidth() / 2, ( float ) bm.getHeight() / 2); try { Bitmap bm1 = Bitmap.createBitmap

OnClickListener两种监听方法

1 //1种:接口OnClickListener ,在onclick响应 2 public class MainActivity extends Activity implements OnClickListener { //这个类前提要接口OnClickListener 3 4 private Button receive; //按钮的初始化 5 private Button falsewifiButton; 6 7 public void init(){ 8 receive=(Button)

Android——Fragment介绍及两种基本使用方法

今天在调ViewPager的时候,感觉ViewPager+Fragment这种做法更灵活,所以,现在拿出来Fragment再整理下. 一,为什么要用Fragment 1,灵活布局 Fragment表现Activity中用UI的一个行为或者一部分.可以组合多个fragment放在一个单独的activity中来创建一个多界面区域的UI,并可以在多个activity里重用某一个fragment.把fragment想象成一个activity的模块化区域,有它自己的生命周期,接收属于它的输入事件,并且可以

工作用到的的两种报表导入方法

工作用到的的两种报表导入方法  两种方法都是给予poi的 the one: 工作需要,导入几分不同的excel 文件 ,然后一个前辈给了一个半成品的工具类,用了一下,发现只有一部分功能,后来又自己重写成了一个通用的工具类,可以自动将excel数据封装成bean 不多说直接贴代码 package com.yida.common.utils; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja

哈希表冲突的两个解决方法线性探测和分离链接法

1.线性探测法 就是当要插入的行号发生冲突时,往下一个行号存放哈希值,直到没有冲突. 2.分离链接法 就是将一个行号做成链表的形式,如果有这个行号的冲突便新建一个节点将其插入这个行号的链表中. 在Mahout中,FastByIDMap是基于散列的,但它在处理散列冲突时使用的是线性探测,而非分离链接.因为线性探测不必为每个条目新增加一个额外的Map.Entry对象,节省了内存开销:在数据规模很庞大的时候,这种优势更加体现得出来.