哈希,链接法解决冲突

#include<iostream>
using namespace std;

struct ListNode;
typedef struct ListNode *Position;
struct Hash_table;
typedef Hash_table *Hashtab;
typedef Position List;

#define Min_table_size 10

struct ListNode
{
 int Emelent;
 Position Next;
};

struct Hash_table
{
 int Table_size;
 List *Thelist;//指向链表的链表
};

//////////////相关函数声明//////////////////////
Hashtab Inittable(int Table_size);     //初始化一个散列
Position Find(int x, Hashtab H);      //查找元素x,返回对应的位置
int Hash(int x);  //散列函数
void Insert(int Key, Hashtab H);   //在散列中插入元素Key
void Delete(int Key, Hashtab H);   //在散列中删除元素Key

///////////////相关函数定义////////////////////
Hashtab Inittable(int table_size)
{
 Hashtab H;
 if (table_size < Min_table_size)
 {
  cout << "Table size is too small" << endl;
  return NULL;
 }

H = (Hashtab)malloc(sizeof(Hash_table));
 if (H == NULL)  cout << "out of space" << endl;
 H->Table_size = table_size;
 H->Thelist = (List*)malloc(sizeof(Position) * H->Table_size);//不知道Position里头有多少个元素也可以分配内存吗
 if (H->Thelist == NULL) cout << "out of space" << endl;
 for (int i = 0; i != H->Table_size; ++i)
 {
  H->Thelist[i] = (Position)malloc(sizeof(ListNode));
  if (H->Thelist[i] == NULL) cout << "out of space" << endl;
  else
  {
   H->Thelist[i]->Emelent = i;
   H->Thelist[i]->Next = NULL;
  }
 }
 return H;
}

int Hash(int x)   //对10取余数
{
 return x % 10;
}

Position Find(int x, Hashtab H)
{
 Position P;
 List L;

L = H->Thelist[Hash(x)];  //指向含有那个元素的表头
 P = L->Next;
 while (P != NULL && P->Emelent != x)
  P = P->Next;
 return P;
}

void Insert(int Key, Hashtab H)
{
 Position Pos, Newcell;
 List L;
 Pos = Find(Key, H);  //先找找看,有没有Key,有就算了
 if (Pos == NULL)
 {
  Newcell = (Position)malloc(sizeof(ListNode));
  if (Newcell == NULL)  cout << "out of space" << endl;
  else    //插入到槽后面的第一个位置
  {
   L = H->Thelist[Hash(Key)];
   Newcell->Next = L->Next;
   Newcell->Emelent = Key;
   L->Next = Newcell;
  }
 }
}

void Delete(int Key, Hashtab H)
{
 Position p, Tmpcell;
 List L;
 p = Find(Key, H);
 if (p == NULL)
  cout << "not find the " << Key << endl;
 else
 {
  L = H->Thelist[Hash(Key)];
  p = L;
  while (p->Next != NULL && p->Next->Emelent != Key)   //寻找Key的前驱节点
  {
   p = p->Next;
  }
  //
  Tmpcell = p->Next;
  p->Next = Tmpcell->Next;
  free(Tmpcell);
 }

}
int main()
{
 Hashtab H = Inittable(11);
 cout << H->Thelist[9]->Emelent << endl;
 Insert(1, H);
 Insert(4, H);
 Insert(9, H);
 Insert(16, H);
 Insert(25, H);
 Insert(19, H);
 Insert(29, H);
 Delete(19, H);
 
 cout << H->Thelist[9]->Next->Next->Emelent << endl;
 return 0;
}

原文地址:https://www.cnblogs.com/Rakint/p/9795428.html

时间: 2024-11-05 14:46:45

哈希,链接法解决冲突的相关文章

数据结构--散列(分离链接法解决冲突)

散列方法的主要思想是根据结点的关键码值来确定其存储地址:以关键码值K为自变量,通过一定的函数关系h(K)(称为散列函数),计算出对应的函数值来,把这个值解释为结点的存储地址,将结点存入到此存储单元中.检索时,用同样的方法计算地址,然后到相应的 单元里去取要找的结点.通过散列方法可以对结点进行快速检索.散列(hash,也称"哈希")是一种重要的存储方式,也是一种常见的检索方法. 因此,散列函数更像是一种映射,散列函数的选择有很多种,下面以散列函数为关键值对10取余为例,说明散列的插入关键

【散列表-链接法解决冲突】利用链接法来解决冲突的散列表

~~~~(>_<)~~~~,搞了好几天终于把这个做出来了.. 首先看一下这种散列表的结构: 1.每个槽都令其为NULL,注意里面保存的都是指向Node的指针,而不是结点哦~ 2.然后我这里把链表的头结点,比如上图的k1,k5,k8的prior指针指向了T这个散列表,因为这样删除的时候会比较简单. 3.注意删除链表中的第一个结点和尾结点时候的不同方法哦..因为这个耽误了3天时间啊... 好了,代码如下: #include<stdio.h> #include<stdlib.h&g

算法学习 - Hash Table操作,分离链接法解决哈希冲突

分离链接法 hash table是映射机制的,最大的优点就是它的操作是O(1)级别的.但是会出现哈希冲突,这就需要几种办法来解决.这里先说一种:分离链接法. 就是当插入的位置已经存在一个值之后,那么在这个值之后插入,就可以了,也叫拉链法.(但是其实会降低查找速度,变成O(n)级别) 下面是代码: // // main.cpp // HashTable_SeparateChaining // // Created by Alps on 14-8-5. // Copyright (c) 2014年

哈希表之开地址法解决冲突

在上一篇博文中,我们讲述了使用链地址法解决冲突的方法.这里我们介绍另一种方式:开地址法解决冲突. 基本思想:当关键码key的哈希地址H0 = hash(key)出现冲突时,以H0为基础,产生另一个哈希地址H1 ,如果H1仍然冲突,再以H0 为基础,产生另一个哈希地址H2 ,-,直到找出一个不冲突的哈希地址Hi ,将相应元素存入其中.根据增量序列的取值方式不同,相应的再散列方式也不同.主要有以下四种: 线性探测再散列 二次探测再散列 伪随机探测再散列 双散列法 (一)线性探测再散列 理解起来很简单

POJ 3349 Snowflake Snow Snowflakes 哈希(链式解决冲突)

题意:n个数列 每个数列6个元素a[i],a[i]<=1e7,两个数列只要,经过若干次循环移动能相等则定义为相似.n<=1e5,问n个数列中 是否存在两个数列相似? 每个数列只有6个数,则相似的最多12种,对每个数列算出其hash值 相同hash值插入同一个链表中.查看新输入的数列插入时是否产生冲突即可 O(n*12) #include <iostream> #include <cstdio> #include <cstring> #include <

[ACM] POJ 3349 Snowflake Snow Snowflakes(哈希查找,链式解决冲突)

Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 30512   Accepted: 8024 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Y

拉链法解决hashtable冲突问题

拉链法解决冲突.拉链法解决冲突的做法是将所有的相同Hash值的key放在一个链表中,比如key3和key14在hash之后都是0,那么在数组的键为0的地方存储这两个值,形式是链表.如果不能理解我的文字,请看下面的示例,看一下打印信息就明白了.拉链法是什么,就是链表. class HashNode{ public $key; public $value; public $nextNode; public function __construct($key, $value, $nextNode=Nu

分离链接法实现散列表

散列表是一种用于查找的数据结构.其基本思想来自于索引,也可以看成是数组的一种扩展.对于一些数据信息,比如说图片文件名,如果我们要查找某张图片,通常将图片名作为关键字进行搜索.这个时候是不可能把图片名直接当成数组下标的,因此可以将图片名关键字通过某个函数映射为某个地址,或地址偏移量.那么每次要查找图片的时候直接输入关键字就能直接计算得出存储地址.其定义 T=h(k) 其中k为关键字,h为映射函数,T为得到的散列表,得到的函数值为地址或地址偏移量. 如果不同关键字通过某函数得到的散列值(地址偏移量)

hash算法解决冲突的方案

1, 开放定址法: 所谓的开放定址法就是一旦发生了冲突,就去寻找下一个空的散列地址,只要散列表足够大,空的散列地址总能找到,并将记录存入 公式为:fi(key) = (f(key)+di) MOD m (di=1,2,3,……,m-1) ※ 用开放定址法解决冲突的做法是:当冲突发生时,使用某种探测技术在散列表中形成一个探测序列.沿此序列逐个单元地查找,直到找到给定的关键字,或者 碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元).查找时