数据结构之散列(开放定址法)

 1 // OHash
 2 // 关键字:int
 3 // Hash函数:hash(X) = X mod TableSize
 4 // 冲突解决方法:开放定址法。Index(X, i) = (hash(X) + f(i)) mod TableSize, f(0) = 0
 5 // 其中f(i)为:
 6 // 1. 线性, f(i) = i
 7 // 2. 平方, f(i) = i ^ 2
 8 // 3. 双散列, f(i) = i * hash2(X), hash2(X, R) = R - (X mod R), R = 7
 9
10 // 前缀:OHash
11
12 #ifndef _OHASH_H
13 #define _OHASH_H
14
15 #define OHASH_DEFAULT_CAPACITY 10
16
17 // 已被插入值, 空, 惰性删除
18 enum KindOfEntry { Legitimate, Empty, Deleted };
19
20 typedef unsigned int Rank;       // 数组,寻秩访问
21 typedef int OHash_T;
22 typedef struct {
23     OHash_T Elem;
24     enum KindOfEntry Info;  // 当前节点状态信息
25 }OHashEntry;
26 typedef struct {
27     int TableSize;
28     OHashEntry *TheEntrys;      // OHashEntry数组
29 } OHashNode;
30 typedef OHashNode *OHash;
31
32
33 // 创建,销毁
34 OHash OHash_Create( int TableSize );
35 void OHash_Destroy( OHash *Phash );
36
37 // 增(改) 删 查
38 // 向H中插入E,若E已经存在,则什么也不做
39 void OHash_Insert( OHash H, OHash_T E );
40 // 从H中惰性删除E,若E不存在,则什么也不做
41 void OHash_Delete( OHash H, OHash_T E );
42 // 查找E在H中的位置(下标),若E不存在,返回-1。
43 // 即使其值为E,若状态为Deleted,仍返回-1
44 Rank OHash_Find( OHash H, OHash_T E );
45 // test
46 void Test_OHashPrint( OHash H );
47
48 #endif /* _OHASH_H */

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include "ohash.h"
  4
  5 // hash(X) = X mod TableSize
  6 static int hash(OHash_T X, int TableSize)
  7 {
  8     return (unsigned int)X % TableSize;
  9 }
 10
 11 // hash2(X, R) = R - (X mod R)
 12 static int hash2(OHash_T X, int R)
 13 {
 14     return R - (unsigned int)X % R;
 15 }
 16
 17 // 冲突处理,其中f(0) = 0
 18 // 1. 线性, f(i) = i
 19 // 2. 平方, f(i) = i ^ 2
 20 // 3. 双散列, f(i) = i * hash2(X, R)
 21 static int f(OHash_T X, int I)
 22 {
 23     //return I;               // 线性
 24     return I * I;           // 平方
 25     //return I * hash2(X, 7); // 双散列 测试R = 7
 26 }
 27
 28 // 将X映射到下标
 29 // Index(X, i) = (hash(X) + f(i)) mod TableSize, f(0) = 0
 30 static Rank Index(OHash_T X, int I, int TableSize)
 31 {
 32     return (hash(X, TableSize) + f(X, I)) % TableSize;
 33 }
 34
 35 // 创建 销毁
 36 OHash OHash_Create(int TableSize)
 37 {
 38     if(TableSize < OHASH_DEFAULT_CAPACITY) {
 39         TableSize = OHASH_DEFAULT_CAPACITY;
 40     }
 41     OHash hash = (OHash)malloc(sizeof(OHashNode));
 42     if(hash == NULL) {
 43         printf("Out of space!!");
 44         return NULL;
 45     }
 46     hash->TableSize = TableSize;
 47     hash->TheEntrys = (OHashEntry *)malloc(sizeof(OHashEntry) * hash->TableSize);
 48     if(hash->TheEntrys == NULL) {
 49         printf("Out of space!!");
 50         free(hash);
 51         return NULL;
 52     }
 53
 54     // 将TheEntrys数组中的InFo设为 Empty
 55     for(int i = 0; i < hash->TableSize; i++) {
 56         hash->TheEntrys[i].Info = Empty;
 57     }
 58
 59     return hash;
 60 }
 61
 62 void OHash_Destroy(OHash *Phash)
 63 {
 64     if(Phash != NULL && *Phash != NULL) {
 65         OHash hash = *Phash;
 66         free(hash->TheEntrys);
 67         free(hash);
 68         *Phash = NULL;
 69     }
 70 }
 71
 72 // 增(改) 删 查
 73 // 向H中插入E,若E已经存在,则什么也不做
 74 void OHash_Insert( OHash H, OHash_T E)
 75 {
 76     if(H == NULL) return ;
 77     int i = 0;
 78     Rank index = 0;
 79     printf("Insert Elem %d: ", E);
 80     while(1) {
 81         index = Index(E, i, H->TableSize);
 82         printf("%d, ", index);
 83         // 两个因素: Info(Legitimate, Empty, Deleted), Elem is E(Y, N)。共 3 * 2 = 6种可能
 84         // 列表如下:
 85         // Elem is E \ Info     Le          Em      De
 86         //          Y           插入        插入    插入
 87         //          N           下一个位置  插入    插入
 88
 89         // 注:此处测试用例
 90         // 1. Add V, Add ..., Add V
 91         // 2. Add V, Delete V, Add V
 92         if( H->TheEntrys[ index ].Elem != E && H->TheEntrys[ index ].Info == Legitimate )
 93         {
 94             i++;
 95         } else {    // 插入
 96             H->TheEntrys[ index ].Elem = E;
 97             H->TheEntrys[ index ].Info = Legitimate;
 98             break;
 99         }
100     }
101     printf("\n");
102 }
103
104 // 从H中惰性删除E,若E不存在,则什么也不做
105 void OHash_Delete(OHash H, OHash_T E)
106 {
107     if(H == NULL) return ;
108
109     Rank index = OHash_Find(H, E);
110     if( index != -1 ) {
111         H->TheEntrys[ index ].Info = Deleted;
112         // H->TheEntrys[ index ].Info = Empty; // 如非惰性删除,将会影响之后的查找
113     }
114 }
115
116 // 查找E在H中的位置(下标),若E不存在,返回-1。
117 // 即使其值为E,若状态为Deleted,仍返回-1
118 Rank OHash_Find(OHash H, OHash_T E)
119 {
120     if(H == NULL) return -1;
121     int index = 0, i = 0;
122     while(1) {
123         // 两个因素: Info(Legitimate, Empty, Deleted), Elem is E(Y, N)。共 3 * 2 = 6种可能
124         // 列表如下:
125         // Elem is E \ Info     Le          Em      De
126         //          Y           index       -1      -1
127         //          N           下一个位置  -1      下一个位置
128
129         // 测试用例:
130         // 1. Add V, Delete V, Find V
131         index = Index(E, i, H->TableSize);
132         if( H->TheEntrys[ index ].Info == Empty ) {
133             return -1;
134         } else {
135             if ( H->TheEntrys[ index ].Elem != E ) {
136                 i++;
137             } else {
138                 if( H->TheEntrys[ index ].Info == Legitimate ) {
139                     return index;
140                 } else if( H->TheEntrys[ index ].Info == Deleted ) {
141                     return -1;
142                 }
143             }
144         }
145     }
146 }
147
148 // test
149 void Test_OHashPrint( OHash H )
150 {
151     if(H == NULL) {
152         printf("OHash is NULL.\n");
153     }
154     for(int i = 0; i < H->TableSize; i++) {
155         if (H->TheEntrys[i].Info == Empty ) {
156             printf("--E ");
157         } else if(H->TheEntrys[i].Info == Deleted) {
158             printf("%dD ", H->TheEntrys[i].Elem);
159         } else {
160             printf("%dL ", H->TheEntrys[i].Elem);
161         }
162     }
163     printf("\n");
164 }

ohash.c

原文地址:https://www.cnblogs.com/KaiQiang123/p/8605513.html

时间: 2024-10-09 22:51:39

数据结构之散列(开放定址法)的相关文章

数据结构--开放定址法解决散列冲突时几种探测法的比较

开放定址法解决散列冲突时主要有线性探测法,平方探测法和双散列法,以下代码通过插入大量随机数,来统计几种探测法产生冲突的次数. #include<iostream> using namespace std; #define MinTablesize 10 #define Num 3000 typedef unsigned int Index; typedef Index Position; struct Hashtal; typedef struct Hashtal *Hashtable; in

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

散列表的实现经常叫做散列. 散列是一种用以常数平均时间运行插入.删除,和查找的技术.可是那些须要元素信息排序的树操作不会得到支持. 因此比如findMax,findMin以及排序后遍历这些操作都是散列不支持的. 假设当一个元素被插入时与已经插入的元素散列(比方散列表的数组序号,非常多元素插入到同一个数组序号中).那么就会产生一个冲突,这个冲突须要消除.解决冲突的办法有两种: 1 分离链接法 2  开放定址法(包含线性探測,平方探測,双散列) 两者都有可能须要再散列 以下说明分离链接法,上代码:

C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等

参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/wangjun1234/p/3719635.html 源代码版本为 .NET Framework 4.6.1 Dictionary是Hashtable的一种泛型实现(也是一种哈希表)实现了IDictionary泛型接口和非泛型接口等,将键映射到相应的值.任何非 null 对象都可以用作键.使用与Hashtable不同的冲突解决方法,D

哈希表(开放定址法处理冲突)(1013)

Description 采用除留余数法(H(key)=key %n)建立长度为n的哈希表,处理冲突用开放定址法的线性探测. Input 第一行为哈希表的长度n: 第二行为关键字的个数: 第三行为关键字集合: 第三行为要查找的数据. Output 如果查找成功,输出关键字所哈希表中的地址和比较次数:如果查找不成功,输出-1. 如果查找成功,输出关键字所哈希表中的地址和比较次数:如果查找不成功,输出-1. Sample Input   1 2 3 4 5 13 11 16 74 60 43 54 9

散列表的C语言实现-开放定址法

头文件: #ifndef __HASHTABLE_H #define __HASHTABLE_H /*********************(平方)开放定址散列法***************/ //如果有冲突发生,那么就尝试另外的单元,直到找到空的单元为止 typedef unsigned int index; typedef index position; typedef int ElementType; #define MINTABLESIZE 5 struct hashTable; t

数据结构(Java语言)——HashTable(开放定址法)简单实现

分离链接散列算法的缺点是使用一些链表.由于给新单元分配地址需要时间,因此这就导致算法的速度有些减慢,同时算法实际上还要求对第二种数据结构的实现.另有一种不用链表解决冲突的方法是尝试另外一些单元,直到找出空的单元为止.更常见的是,单元h0(x),h1(x),h2(x),...相继被试选,其中hi(x)=(hash(x)+f(i)) mod TableSize,且f(0)=0.函数f是冲突解决方法,因为所有的数据都要置于表内,所以这种解决方案所需要的表要比分离链接散列的表大.一般来说,对于不使用分离

数据结构--解决散列冲突,平方探测法

上代码: package com.itany.quadraticprobing; import java.util.LinkedList; import java.util.List; //使用平方探测的散列表 来解决散列时的冲突问题 public class QuadraticProbingHashTable<T> { private static final int DEFAULT_TABLE_SIZE=11; private HashEntry<T>[] array; pri

算法:开放定址法散列表

hash.h #ifndef _HASHQUAD_H #define _HASHQUAD_H #define MinTableSize 10 struct HashEntry; struct HashNode; typedef char *ElementType; typedef unsigned int Index; typedef Index Position; typedef struct HashNode *HashTable; typedef struct HashEntry *Cel

【散列表-直接定址法】含有卫星数据的直接定址法

数组T中的每个值都是指针,指针指向node结点,node结点中的元素为key,data. 代码: #include<stdio.h> #include<stdlib.h> typedef struct Node { int key; int data; }Node; typedef struct T { Node **table;//利用指针数组 int size; }T; void T_create(T *t) { printf("关键字全域U是多少?\n")