哈希查找算法的源代码 c语言
c语言哈希库函数
c语言哈希库函数一、概述哈希表是一种常见的数据结构,用于实现键值对的快速查找。
C语言中没有内置的哈希表库,但可以通过编写自己的哈希库函数来实现相同的功能。
本文将介绍如何编写一个基本的哈希库函数。
二、哈希函数哈希函数是将键映射到索引的算法。
它应该满足以下要求:1. 对于相同的键,始终返回相同的索引。
2. 对于不同的键,尽可能返回不同的索引。
3. 将键均匀地分布在索引范围内。
常用的哈希函数包括除留余数法、乘法散列法和SHA等。
下面是一个简单的除留余数法哈希函数:```unsigned int hash(char *key, int size) {unsigned int hashval = 0;for (int i = 0; key[i] != '\0'; i++) {hashval = key[i] + 31 * hashval;}return hashval % size;}```该函数将每个字符转换为ASCII码并加权求和,然后使用除留余数法将结果映射到索引范围内。
三、数据结构为了实现哈希表,我们需要定义一个包含以下成员变量的结构体:```typedef struct {char *key;void *value;} HashNode;typedef struct {int size;int count;HashNode **nodes;} HashTable;```其中,HashNode表示哈希表中的一个键值对,key为键,value为值。
HashTable包含三个成员变量:1. size:哈希表的大小。
2. count:哈希表中键值对的数量。
3. nodes:指向HashNode指针数组的指针。
四、初始化函数在使用哈希表之前,需要先创建一个空的HashTable对象。
下面是一个简单的初始化函数:```HashTable *hash_init(int size) {HashTable *table = malloc(sizeof(HashTable));table->size = size;table->count = 0;table->nodes = calloc(size, sizeof(HashNode *));return table;}```该函数分配内存并将成员变量初始化为初始值。
c++字符串哈希计算
在C++中,计算字符串的哈希值通常涉及到使用某种哈希函数。
哈希函数将输入(在这种情况下是字符串)转换为固定大小的输出,通常是整数。
这个输出被称为哈希值或哈希码。
在C++标准库中,没有内置的字符串哈希函数,但你可以使用第三方库,如Boost,或者自己实现一个简单的哈希函数。
另外,C++11引入了std::hash模板类,它可以用于获取标准类型的哈希值,包括std::string。
下面是一个使用std::hash来计算字符串哈希值的例子:cpp#include <iostream>#include <string>#include <functional>int main() {std::string str = "Hello, World!";std::hash<std::string> hasher;size_t hash = hasher(str);std::cout << "Hash value of \"" << str << "\" is: " << hash << std::endl; return 0;}在这个例子中,我们使用了std::hash<std::string>来创建一个字符串哈希函数对象。
然后,我们通过调用这个函数对象并传入我们的字符串来计算哈希值。
最后,我们打印出计算得到的哈希值。
请注意,不同的编译器和平台可能会产生不同的哈希值,因为C++标准并没有规定std::hash 的具体实现。
因此,如果你需要跨平台的一致性,你可能需要使用一个特定的哈希算法,如MD5、SHA-1或SHA-256,这些都可以通过第三方库(如OpenSSL或Crypto++)来实现。
然而,这些算法通常用于密码学和数据完整性检查,而不是普通的哈希表查找。
c语言开源hash项目——uthash
c语言开源 hash项目 ——uthash
1 //------------------------------------------
2 // c语言 开源hash项目 —— uthash
3 //
4 //
5 //eg: 对 字符串进行查找和删除 字符指针
6 //
7 // warning: uthash 对 字符指针和字符数组,
8 //
插入的函数是不一样的,查找的函数是一致的
9 //
对所有的类型,删除的操作
10 //-------------------------------------------
21 UT_hash_handle hh;
22 }uthash_int;
23
24 // 查找
25 uthash_int *find_uthash_int(uthash_int *g_users, int ikey)
26 {
27 uthash_int *s = NULL;
28 HASH_FIND_INT(g_users, &ikey, s);
11
12 #include "gtest/gtest.h"
13 #include <iostream>
14 using namespace std;
15
16 #include"uthash/uthash.h"
17
18 typedef struct {
常用Hash算法(C语言的简单实现)
常⽤Hash算法(C语⾔的简单实现)如下所⽰:#include "GeneralHashFunctions.h"unsigned int RSHash(char* str, unsigned int len){unsigned int b = 378551;unsigned int a = 63689;unsigned int hash = 0;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = hash * a + (*str);a = a * b;}return hash;}/* End Of RS Hash Function */unsigned int JSHash(char* str, unsigned int len){unsigned int hash = 1315423911;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash ^= ((hash << 5) + (*str) + (hash >> 2));}return hash;}/* End Of JS Hash Function */unsigned int PJWHash(char* str, unsigned int len){const unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);const unsigned int ThreeQuarters = (unsigned int)((BitsInUnsignedInt * 3) / 4);const unsigned int OneEighth = (unsigned int)(BitsInUnsignedInt / 8);const unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);unsigned int hash = 0;unsigned int test = 0;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = (hash << OneEighth) + (*str);if((test = hash & HighBits) != 0){hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));}}return hash;}/* End Of P. J. Weinberger Hash Function */unsigned int ELFHash(char* str, unsigned int len){unsigned int hash = 0;unsigned int x = 0;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = (hash << 4) + (*str);if((x = hash & 0xF0000000L) != 0){hash ^= (x >> 24);}hash &= ~x;}return hash;}/* End Of ELF Hash Function */unsigned int BKDRHash(char* str, unsigned int len){unsigned int seed = 131; /* 31 131 1313 13131 131313 etc.. */ unsigned int hash = 0;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = (hash * seed) + (*str);}return hash;}/* End Of BKDR Hash Function */unsigned int SDBMHash(char* str, unsigned int len){unsigned int hash = 0;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = (*str) + (hash << 6) + (hash << 16) - hash;}return hash;}/* End Of SDBM Hash Function */unsigned int DJBHash(char* str, unsigned int len){unsigned int hash = 5381;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = ((hash << 5) + hash) + (*str);}return hash;}/* End Of DJB Hash Function */unsigned int DEKHash(char* str, unsigned int len){unsigned int hash = len;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = ((hash << 5) ^ (hash >> 27)) ^ (*str);}return hash;}/* End Of DEK Hash Function */unsigned int BPHash(char* str, unsigned int len){unsigned int hash = 0;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash = hash << 7 ^ (*str);}return hash;}/* End Of BP Hash Function */unsigned int FNVHash(char* str, unsigned int len){const unsigned int fnv_prime = 0x811C9DC5;unsigned int hash = 0;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash *= fnv_prime;hash ^= (*str);}return hash;}/* End Of FNV Hash Function */unsigned int APHash(char* str, unsigned int len){unsigned int hash = 0xAAAAAAAA;unsigned int i = 0;for(i = 0; i < len; str++, i++){hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (*str) * (hash >> 3)) :(~((hash << 11) + ((*str) ^ (hash >> 5))));}return hash;}/* End Of AP Hash Function */以上就是⼩编为⼤家带来的常⽤Hash算法(C语⾔的简单实现)的全部内容了,希望对⼤家有所帮助,多多⽀持~。
C语言中的搜索算法详解
C语言中的搜索算法详解搜索算法在计算机科学中起着重要的作用,它们可以帮助我们在大量数据中迅速找到目标元素。
在C语言中,有多种搜索算法可供选择。
本文将深入探讨一些常用的搜索算法,包括线性搜索、二分搜索和哈希表搜索。
一、线性搜索线性搜索是最简单的搜索算法之一,也被称为顺序搜索。
它逐个比较列表中的元素,直到找到目标元素或搜索完整个列表。
这种算法适用于无序列表,并且其时间复杂度为O(n),其中n为列表的长度。
在C语言中,我们可以使用for循环来实现线性搜索算法。
下面是一个示例代码:```c#include <stdio.h>int linear_search(int arr[], int n, int target) {for(int i = 0; i < n; i++) {if(arr[i] == target) {return i;}}return -1;}int main() {int arr[] = {1, 2, 3, 4, 5};int n = sizeof(arr) / sizeof(arr[0]);int target = 3;int result = linear_search(arr, n, target);if(result != -1) {printf("目标元素在列表中的索引为:%d\n", result);} else {printf("目标元素不在列表中。
\n");}return 0;}```二、二分搜索二分搜索是一种更有效的搜索算法,前提是列表已经按照升序或降序排列。
它通过将目标元素与列表的中间元素进行比较,并根据比较结果将搜索范围缩小一半。
这种算法的时间复杂度为O(logn),其中n 为列表的长度。
在C语言中,我们可以使用递归或迭代的方式实现二分搜索算法。
下面是一个使用迭代方式实现的示例代码:```c#include <stdio.h>int binary_search(int arr[], int low, int high, int target) {while(low <= high) {int mid = (low + high) / 2;if(arr[mid] == target) {return mid;} else if(arr[mid] < target) {low = mid + 1;} else {high = mid - 1;}}return -1;}int main() {int arr[] = {1, 2, 3, 4, 5};int n = sizeof(arr) / sizeof(arr[0]);int target = 3;int result = binary_search(arr, 0, n - 1, target);if(result != -1) {printf("目标元素在列表中的索引为:%d\n", result);} else {printf("目标元素不在列表中。
SHA1算法源代码
SHA1算法源代码SHA-1(Secure Hash Algorithm 1)是一种常见的哈希算法,用于生成哈希值,常用于密码学和安全领域。
下面是SHA-1算法的详细源代码:```pythonimport struct#初始化常数h1=0xEFCDAB89h2=0x98BADCFEh4=0xC3D2E1F0def sha1(message):"""输入:字符串message输出:字符串的SHA-1哈希值"""#补位original_length = len(message) * 8message += b'\x80'while (len(message) + 8) % 64 != 0:message += b'\x00'message += struct.pack('>Q', original_length)#分组blocks = []for i in range(0, len(message), 64):block = message[i:i+64]blocks.append(block)#处理每个分组for block in blocks:w = list(struct.unpack('>16I', block))#扩展消息for i in range(16, 80):w.append(left_rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1))#初始化哈希值a=h0b=h1c=h2d=h3e=h4#执行80轮循环for i in range(0, 80):if 0 <= i < 20:f=(b&c),((~b)&d)elif 20 <= i < 40:f=b^c^dk=0x6ED9EBA1elif 40 <= i < 60:f=(b&c),(b&d),(c&d)k=0x8F1BBCDCelse:f=b^c^dk=0xCA62C1D6temp = (left_rotate(a, 5) + f + e + k + w[i]) & 0xffffffff e=dd=cc = left_rotate(b, 30)b=aa = temp#更新哈希值h0 = (h0 + a) & 0xffffffffh1 = (h1 + b) & 0xffffffffh2 = (h2 + c) & 0xffffffffh3 = (h3 + d) & 0xffffffffh4 = (h4 + e) & 0xffffffff#输出哈希值digest = struct.pack('>5I', h0, h1, h2, h3, h4)return digest.hexdef left_rotate(n, b):"""左旋转n"""return ((n << b) , (n >> (32 - b))) & 0xffffffff```上面的代码实现了SHA-1算法的核心部分。
hashCode--C++源码
intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {if (UseBiasedLocking) {// NOTE: many places throughout the JVM do not expect a safepoint// to be taken here, in particular most operations on perm gen// objects. However, we only ever bias Java instances and all of// the call sites of identity_hash that might revoke biases have// been checked to make sure they can handle a safepoint. The// added check of the bias pattern is to avoid useless calls to// thread-local storage.if (obj->;mark()->;has_bias_pattern()) {// Box and unbox the raw reference just in case we cause a STW safepoint. Handle hobj (Self, obj) ;// Relaxing assertion for bug 6320749.assert (Universe::verify_in_progress() ||!SafepointSynchronize::is_at_safepoint(),";biases should not be seen by VM thread here";);BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current()); obj = hobj() ;assert(!obj->;mark()->;has_bias_pattern(), ";biases should be revoked by now";);}}// hashCode() is a heap mutator ...// Relaxing assertion for bug 6320749.assert (Universe::verify_in_progress() ||!SafepointSynchronize::is_at_safepoint(), ";invariant";) ;assert (Universe::verify_in_progress() ||Self->;is_Java_thread() , ";invariant";) ;assert (Universe::verify_in_progress() ||((JavaThread *)Self)->;thread_state() != _thread_blocked, ";invariant";) ;ObjectMonitor* monitor = NULL;markOop temp, test;intptr_t hash;markOop mark = ReadStableMark (obj);// object should remain ineligible for biased lockingassert (!mark->;has_bias_pattern(), ";invariant";) ;if (mark->;is_neutral()) {hash = mark->;hash(); // this is a normal headerif (hash) { // if it has hash, just returnreturn hash;}hash = get_next_hash(Self, obj); // allocate a new hash codetemp = mark->;copy_set_hash(hash); // merge the hash code into header// use (machine word version) atomic operation to install the hashtest = (markOop) Atomic::cmpxchg_ptr(temp, obj->;mark_addr(), mark);if (test == mark) {return hash;}// If atomic operation failed, we must inflate the header// into heavy weight monitor. We could add more code here// for fast path, but it does not worth the complexity.} else if (mark->;has_monitor()) {monitor = mark->;monitor();temp = monitor->;header();assert (temp->;is_neutral(), ";invariant";) ;hash = temp->;hash();if (hash) {return hash;}// Skip to the following code to reduce code size} else if (Self->;is_lock_owned((address)mark->;locker())) {temp = mark->;displaced_mark_helper(); // this is a lightweight monitor owned assert (temp->;is_neutral(), ";invariant";) ;hash = temp->;hash(); // by current thread, check if the displacedif (hash) { // header contains hash code return hash;}// WARNING:// The displaced header is strictly immutable.// It can NOT be changed in ANY cases. So we have// to inflate the header into heavyweight monitor// even the current thread owns the lock. The reason// is the BasicLock (stack slot) will be asynchronously// read by other threads during the inflate() function.// Any change to stack may not propagate to other threads// correctly.}// Inflate the monitor to set hash codemonitor = ObjectSynchronizer::inflate(Self, obj);// Load displaced header and check it has hash codemark = monitor->;header();assert (mark->;is_neutral(), ";invariant";) ;hash = mark->;hash();if (hash == 0) {hash = get_next_hash(Self, obj);temp = mark->;copy_set_hash(hash); // merge hash code into headerassert (temp->;is_neutral(), ";invariant";) ;test = (markOop) Atomic::cmpxchg_ptr(temp, monitor, mark);if (test != mark) {// The only update to the header in the monitor (outside GC)// is install the hash code. If someone add new usage of// displaced header, please update this codehash = test->;hash();assert (test->;is_neutral(), ";invariant";) ;assert (hash != 0, ";Trivial unexpected object/monitor header usage.";); }}// We finally get the hashreturn hash;}。
c语言自带的hash函数
c语言自带的hash函数C语言自带的哈希函数指的是stdlib库中提供的哈希算法函数。
在C语言中,stdlib库是一个通用的标准库,提供了一系列常用的函数,其中包括很多常用的哈希算法函数。
在实际编程中,使用stdlib库中的哈希函数可以方便快捷地完成各种哈希操作。
具体来说,stdlib库中提供了两个常用的哈希函数,分别是:1. hash()2. hcreate()其中,hash()函数用于计算给定键值的哈希值,而hcreate()函数用于创建一个哈希表。
下面将逐一介绍这两个函数的详细用法和作用。
1. hash()函数hash()函数是stdlib库中提供的一个常用的哈希算法函数,用于计算给定键值的哈希值。
该函数可以用于任何数据结构的哈希表中,包括数组、字符串、结构体等等。
hash()函数的定义如下:unsigned hash(const void *key, size_t length)其中,key为输入的键值,length为键值的长度。
该函数的返回值为一个unsigned整数,表示计算出来的哈希值。
在使用hash()函数时,需要注意以下几点:(1)键值必须以一个void类型的指针的形式传递给hash()函数,并使用length 指定键值的长度。
(2)哈希值的计算结果是一个无符号整数,其取值范围为[0, 4294967295]。
(3)hash()函数使用了一个简单的算法来计算哈希值。
该算法会按位操作键值,并使用数学运算将位运算结果组合成一个哈希值。
2. hcreate()函数hcreate()函数是stdlib库中提供的一个用于创建哈希表的函数。
该函数可以用于创建任何种类的哈希表,包括使用链表或数组实现的哈希表。
关于hcreate()函数的使用,以下是一些常见的注意事项:(1)创建哈希表时,需要事先确定哈希表的大小,然后将该大小作为参数传递给hcreate()函数。
(2)hcreate()函数返回值为0时表示成功创建哈希表,否则表示创建哈希表失败。
c语言 位运算 计算 hash码
c语言位运算计算hash码一、概述在计算机科学和信息技术领域中,hash码是一种重要的数据结构,它能够将数据映射到一个固定长度的唯一标识符上。
在实际应用中,hash码常常被用于加速数据存储和查找的速度,因此对于计算hash 码的方法和效率的研究变得尤为重要。
而位运算作为c语言中的一种常用操作,其高效的处理速度,使得它成为计算hash码的一个重要工具。
本文将介绍位运算在c语言中计算hash码的方法及其实际应用。
二、位运算的基础知识1. 位运算的基本操作位运算是指对二进制数进行的一种操作,其基本操作包括与()、或(|)、异或(^)、取反(~)、左移(<<)和右移(>>)等。
这些操作可以对二进制数据进行高效的处理,常用于编写底层的算法和数据结构。
2. 位运算的特点位运算具有处理速度快、空间效率高等特点,适合于对大规模数据进行高效的处理。
在计算hash码中,合理地利用位运算可以大大提高计算速度和节省计算资源。
三、哈希算法1. 哈希算法的概念哈希算法是指将任意长度的输入数据通过哈希函数变换为固定长度的输出数据的过程。
这个输出数据即为哈希码。
哈希算法常常用于数据加密、数据完整性校验、数据查找等方面。
2. 常见的哈希算法常见的哈希算法包括MD5、SHA-1、SHA-256等。
这些算法具有不同的特点和适用范围,但都能够将输入数据映射为固定长度的哈希码。
四、位运算计算哈希码1. 位运算在哈希码计算中的作用位运算可以通过对二进制数据的操作,使得在计算哈希码时可以高效地进行数据处理。
在c语言中,位运算常常被用于哈希码的计算中,尤其适用于处理大规模数据。
2. 位运算计算哈希码的原理位运算在计算哈希码时,通常通过将数据转换为二进制形式,并利用位运算的与、或、异或等操作进行数据处理。
通过合理地设计位运算的规则,可以得到固定长度的哈希码,并保证数据的唯一性和不可逆性。
3. 位运算计算哈希码的实际应用在实际应用中,位运算计算哈希码常常用于大规模数据的处理和存储。
stm32 c语言 阿里云 哈希算法
stm32 c语言阿里云哈希算法
在STM32中使用C语言实现阿里云的哈希算法,可以采用以下步骤:
1. 安装阿里云的SDK,在头文件中包含"HMAC_SHA1.h"和"HMAC_MD5.h"这两个文件。
2. 配置STM32的加密硬件模块,用于加密操作。
3. 定义密钥和明文,在程序中调用HMAC_MD5或者HMAC_SHA1函数进行哈希算法。
例如:
c
#include "HMAC_SHA1.h"
#include "HMAC_MD5.h"
unsigned char key[16] = "1234567890ABCDEF";
unsigned char text[16] = "hello world";
unsigned char result[SHA1_BLOCK_SIZE];
HMAC_SHA1(key, 16, text, 11, result);
4. 处理加密结果,在使用阿里云服务时,需要将加密结果转换成Base64格式,进行字符串拼接等操作。
可以使用Base64编解码函数进行处理。
例如:
c
#include "base64.h"
unsigned char output[SHA1_BLOCK_SIZE * 2];
Base64_Encode(result, SHA1_BLOCK_SIZE, output);
通过以上步骤,就可以在STM32中使用C语言实现阿里云的哈希算法了。
C语言查找算法技巧
C语言查找算法技巧查找算法是计算机科学中重要的基础概念之一,它可以帮助我们在大量数据中高效地找到目标元素。
在C语言中,有多种查找算法可以选择,各具特点,本文将介绍几种常用的C语言查找算法技巧。
一、线性查找算法线性查找算法是最简单直观的查找算法,它顺序地从头到尾依次比较每个元素和目标元素是否相等。
如果找到了目标元素,则返回元素的索引值;如果遍历完整个列表仍未找到目标元素,则返回-1表示未找到。
下面是一个示例代码,演示了如何使用C语言实现线性查找算法:```c#include <stdio.h>int linearSearch(int arr[], int n, int target) {int i;for(i = 0; i < n; i++) {if(arr[i] == target) {return i; //找到目标元素,返回索引值}}return -1; //未找到目标元素,返回-1}int main() {int arr[] = {2, 4, 6, 8, 10};int n = sizeof(arr) / sizeof(arr[0]); //计算数组长度int target = 8;int result = linearSearch(arr, n, target);if(result == -1) {printf("目标元素未找到\n");} else {printf("目标元素在数组中的索引为:%d\n", result);}return 0;}```二、二分查找算法二分查找算法也被称为折半查找算法,它是一种在有序数组中快速查找目标元素的算法。
它通过将目标元素与有序数组的中间元素进行比较,每次可以将待查找区间缩小一半,从而快速定位目标元素。
下面是一个示例代码,演示了如何使用C语言实现二分查找算法:```c#include <stdio.h>int binarySearch(int arr[], int low, int high, int target) {while(low <= high) {int mid = (low + high) / 2; //计算中间元素索引if(arr[mid] == target) {return mid; //找到目标元素,返回索引值} else if(arr[mid] < target) {low = mid + 1; //目标元素在右半部分,缩小查找区间} else {high = mid - 1; //目标元素在左半部分,缩小查找区间}}return -1; //未找到目标元素,返回-1}int main() {int arr[] = {2, 4, 6, 8, 10};int n = sizeof(arr) / sizeof(arr[0]); //计算数组长度int target = 8;int result = binarySearch(arr, 0, n - 1, target);if(result == -1) {printf("目标元素未找到\n");} else {printf("目标元素在数组中的索引为:%d\n", result);}return 0;}```三、哈希查找算法哈希查找算法基于哈希表数据结构,它通过将目标元素的关键字作为索引,在常量时间内定位目标元素的位置。
C语言获取文件SHA1哈希
C语⾔获取⽂件SHA1哈希安全散列算法(Secure Hash Algorithm)主要适⽤于数字签名标准(Digital Signature Standard DSS)它定义了数字签名算法(Digital Signature Algorithm DSA)。
对于长度⼩于2^64位的消息。
SHA1会产⽣⼀个160位的消息摘要。
当接收到消息的时候,这个消息摘要能够⽤来验证数据的完整性。
在传输的过程中。
数据⾮常可能会发⽣变化,那么这时候就会产⽣不同的消息摘要。
SHA1有例如以下特性:不能够从消息摘要中复原信息。
两个不同的消息不会产⽣相同的消息摘要。
SHA1 C语⾔实现#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <errno.h>#undef BIG_ENDIAN_HOSTtypedef unsigned int u32;/***************** Rotate a 32 bit integer by n bytes*/#if defined(__GNUC__) && defined(__i386__)static inline u32rol( u32 x, int n){__asm__("roll %%cl,%0":"=r" (x):"0" (x),"c" (n));return x;}#else#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )#endiftypedef struct {u32 h0,h1,h2,h3,h4;u32 nblocks;unsigned char buf[64];int count;} SHA1_CONTEXT;voidsha1_init( SHA1_CONTEXT *hd ){hd->h0 = 0x67452301;hd->h1 = 0xefcdab89;hd->h2 = 0x98badcfe;hd->h3 = 0x10325476;hd->h4 = 0xc3d2e1f0;hd->nblocks = 0;hd->count = 0;}/***************** Transform the message X which consists of 16 32-bit-words*/static voidtransform( SHA1_CONTEXT *hd, unsigned char *data ){u32 a,b,c,d,e,tm;u32 x[16];/* get values from the chaining vars */a = hd->h0;b = hd->h1;c = hd->h2;d = hd->h3;e = hd->h4;#ifdef BIG_ENDIAN_HOSTmemcpy( x, data, 64 );#else{int i;unsigned char *p2;for(i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 ) {p2[3] = *data++;p2[2] = *data++;p2[1] = *data++;p2[0] = *data++;}}#endif#define K1 0x5A827999L#define K2 0x6ED9EBA1L#define K3 0x8F1BBCDCL#define K4 0xCA62C1D6L#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )#define F2(x,y,z) ( x ^ y ^ z )#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )#define F4(x,y,z) ( x ^ y ^ z )#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \, (x[i&0x0f] = rol(tm,1)) )#define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \+ f( b, c, d ) \+ k \+ m; \b = rol( b, 30 ); \} while(0)R( a, b, c, d, e, F1, K1, x[ 0] );R( e, a, b, c, d, F1, K1, x[ 1] );R( d, e, a, b, c, F1, K1, x[ 2] );R( c, d, e, a, b, F1, K1, x[ 3] );R( b, c, d, e, a, F1, K1, x[ 4] );R( a, b, c, d, e, F1, K1, x[ 5] );R( e, a, b, c, d, F1, K1, x[ 6] );R( d, e, a, b, c, F1, K1, x[ 7] );R( c, d, e, a, b, F1, K1, x[ 8] );R( b, c, d, e, a, F1, K1, x[ 9] );R( a, b, c, d, e, F1, K1, x[10] );R( e, a, b, c, d, F1, K1, x[11] );R( d, e, a, b, c, F1, K1, x[12] );R( c, d, e, a, b, F1, K1, x[13] );R( b, c, d, e, a, F1, K1, x[14] );R( a, b, c, d, e, F1, K1, x[15] );R( e, a, b, c, d, F1, K1, M(16) );R( d, e, a, b, c, F1, K1, M(17) );R( c, d, e, a, b, F1, K1, M(18) );R( b, c, d, e, a, F1, K1, M(19) );R( a, b, c, d, e, F2, K2, M(20) );R( e, a, b, c, d, F2, K2, M(21) );R( d, e, a, b, c, F2, K2, M(22) );R( c, d, e, a, b, F2, K2, M(23) );R( b, c, d, e, a, F2, K2, M(24) );R( a, b, c, d, e, F2, K2, M(25) );R( e, a, b, c, d, F2, K2, M(26) );R( d, e, a, b, c, F2, K2, M(27) );R( c, d, e, a, b, F2, K2, M(28) );R( b, c, d, e, a, F2, K2, M(29) );R( a, b, c, d, e, F2, K2, M(30) );R( e, a, b, c, d, F2, K2, M(31) );R( d, e, a, b, c, F2, K2, M(32) );R( c, d, e, a, b, F2, K2, M(33) );R( b, c, d, e, a, F2, K2, M(34) );R( a, b, c, d, e, F2, K2, M(35) );R( e, a, b, c, d, F2, K2, M(36) );R( d, e, a, b, c, F2, K2, M(37) );R( c, d, e, a, b, F2, K2, M(38) );R( b, c, d, e, a, F2, K2, M(39) );R( a, b, c, d, e, F3, K3, M(40) );R( e, a, b, c, d, F3, K3, M(41) );R( d, e, a, b, c, F3, K3, M(42) );R( c, d, e, a, b, F3, K3, M(43) );R( b, c, d, e, a, F3, K3, M(44) );R( a, b, c, d, e, F3, K3, M(45) );R( e, a, b, c, d, F3, K3, M(46) );R( d, e, a, b, c, F3, K3, M(47) );R( c, d, e, a, b, F3, K3, M(48) );R( b, c, d, e, a, F3, K3, M(49) );R( a, b, c, d, e, F3, K3, M(50) );R( e, a, b, c, d, F3, K3, M(51) );R( d, e, a, b, c, F3, K3, M(52) );R( c, d, e, a, b, F3, K3, M(53) );R( b, c, d, e, a, F3, K3, M(54) );R( a, b, c, d, e, F3, K3, M(55) );R( e, a, b, c, d, F3, K3, M(56) );R( d, e, a, b, c, F3, K3, M(57) );R( c, d, e, a, b, F3, K3, M(58) );R( b, c, d, e, a, F3, K3, M(59) );R( a, b, c, d, e, F4, K4, M(60) );R( e, a, b, c, d, F4, K4, M(61) );R( d, e, a, b, c, F4, K4, M(62) );R( c, d, e, a, b, F4, K4, M(63) );R( b, c, d, e, a, F4, K4, M(64) );R( a, b, c, d, e, F4, K4, M(65) );R( e, a, b, c, d, F4, K4, M(66) );R( d, e, a, b, c, F4, K4, M(67) );R( c, d, e, a, b, F4, K4, M(68) );R( b, c, d, e, a, F4, K4, M(69) );R( a, b, c, d, e, F4, K4, M(70) );R( e, a, b, c, d, F4, K4, M(71) );R( d, e, a, b, c, F4, K4, M(72) );R( c, d, e, a, b, F4, K4, M(73) );R( b, c, d, e, a, F4, K4, M(74) );R( a, b, c, d, e, F4, K4, M(75) );R( e, a, b, c, d, F4, K4, M(76) );R( d, e, a, b, c, F4, K4, M(77) );R( c, d, e, a, b, F4, K4, M(78) );R( b, c, d, e, a, F4, K4, M(79) );/* Update chaining vars */hd->h0 += a;hd->h1 += b;hd->h2 += c;hd->h3 += d;hd->h4 += e;}/* Update the message digest with the contents* of INBUF with length INLEN.*/static voidsha1_write( SHA1_CONTEXT *hd, unsigned char *inbuf, size_t inlen) {if( hd->count == 64 ) { /* flush the buffer */transform( hd, hd->buf );hd->count = 0;hd->nblocks++;}if( !inbuf )return;if( hd->count ) {for( ; inlen && hd->count < 64; inlen-- )hd->buf[hd->count++] = *inbuf++;sha1_write( hd, NULL, 0 );if( !inlen )return;}while( inlen >= 64 ) {transform( hd, inbuf );hd->count = 0;hd->nblocks++;inlen -= 64;inbuf += 64;}for( ; inlen && hd->count < 64; inlen-- )hd->buf[hd->count++] = *inbuf++;}/* The routine final terminates the computation and* returns the digest.* The handle is prepared for a new cycle, but adding bytes to the* handle will the destroy the returned buffer.* Returns: 20 bytes representing the digest.*/static voidsha1_final(SHA1_CONTEXT *hd){u32 t, msb, lsb;unsigned char *p;sha1_write(hd, NULL, 0); /* flush */;t = hd->nblocks;/* multiply by 64 to make a byte count */lsb = t << 6;msb = t >> 26;/* add the count */t = lsb;if( (lsb += hd->count) < t )msb++;/* multiply by 8 to make a bit count */t = lsb;lsb <<= 3;msb <<= 3;msb |= t >> 29;if( hd->count < 56 ) { /* enough room */hd->buf[hd->count++] = 0x80; /* pad */while( hd->count < 56 )hd->buf[hd->count++] = 0; /* pad */}else { /* need one extra block */hd->buf[hd->count++] = 0x80; /* pad character */while( hd->count < 64 )hd->buf[hd->count++] = 0;sha1_write(hd, NULL, 0); /* flush */;memset(hd->buf, 0, 56 ); /* fill next block with zeroes */}/* append the 64 bit count */hd->buf[56] = msb >> 24;hd->buf[57] = msb >> 16;hd->buf[58] = msb >> 8;hd->buf[59] = msb ;hd->buf[60] = lsb >> 24;hd->buf[61] = lsb >> 16;hd->buf[62] = lsb >> 8;hd->buf[63] = lsb ;transform( hd, hd->buf );p = hd->buf;#ifdef BIG_ENDIAN_HOST#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)#else /* little endian */#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)#endifX(0);X(1);X(2);X(3);X(4);#undef X}控制台调⽤函数:/*输出⽂件的SHA1值* FileNameInPut:⽂件路径*/void GetFileSHA1(char *FileNameInPut){if(FileNameInPut==NULL){printf("\nUsage:\n <EXEFILE> <FILENAME>\n ");return;}FILE *fp;char buffer[4096];size_t n;SHA1_CONTEXT ctx;int i;fopen_s (&fp, FileNameInPut, "rb");if (!fp){printf("打开⽂件“%s”失败\n", FileNameInPut);return;}sha1_init (&ctx);while ( (n = fread (buffer, 1, sizeof buffer, fp))) sha1_write (&ctx, (unsigned char *)buffer, n); if (ferror (fp)){printf("读取⽂件“%s”失败\n", FileNameInPut);return;}sha1_final (&ctx);fclose (fp);for ( i=0; i < 20; i++){printf("%02x",ctx.buf[i]);}}适合程序中调⽤的返回值⽅式:/*获取⽂件的SHA1值,假设错误发⽣则将错误信息写⼊outError* FileNameInPut:⽂件路径* outSHA1:SHA1输出变量* outError:错误信息输出变量* returns:outSHA1*/char *GetFileSHA1(char *FileNameInPut, char *outSHA1, char *outError){if(FileNameInPut==NULL){if (outError != NULL){sprintf(outError, "%s", "FileNameInPut Is NULL");}return outSHA1;}FILE *fp;char buffer[4096];size_t n;SHA1_CONTEXT ctx;int i;fopen_s (&fp, FileNameInPut, "rb");if (!fp){if (outError != NULL){sprintf(outError, "打开⽂件“%s”失败\n", FileNameInPut);}return outSHA1;}sha1_init (&ctx);while ( (n = fread (buffer, 1, sizeof buffer, fp))) sha1_write (&ctx, (unsigned char *)buffer, n);if (ferror (fp)){if (outError != NULL){sprintf(outError, "读取⽂件“%s”失败\n", FileNameInPut);}return outSHA1;}sha1_final (&ctx);fclose (fp);for ( i=0; i < 20; i++){sprintf(outSHA1 + 2*i, "%02x", (unsigned char)ctx.buf[i]);}outSHA1[2*i] = '\0';return outSHA1;}⽔平有限,此⽅法仅仅是简单的实现,还有些问题没有解决,希望⾼⼿指点⼀⼆。
哈希表的c语言操作
}
BOOL InsertHash(HashTable &H,Record e)
{//查找不成功时插入元素 e 到开放定址哈希表 H 中,并返回 True,否则返回 False
int p;
if(SearchHash(H,e.keynum,p)) //表中已有与 e 有相同关键字的元素
return False;
//哈希表元素的三种状态,没有记录、有记录、有过记录但已被删除
typedef struct
//定义哈希表的结构
{int elem[MAXSIZE]; //数据元素体
HAVEORNOT elemflag[MAXSIZE]; //元素状态标志,没有记录、有记录、有过记录但已被
删除
int count; //哈希表中当前元素的个数
int i;
for(i=0;i<MAXSIZE;i++) //显示哈希表中记录所在位置
if(H.elemflag[i]==HAVEKEY) //只显示标志为 HAVEKEY(存放有记录)的元素
printf("%-4d",i);
printf("\n");
哈希表及其常用算法(代码实例)
哈希表及其常⽤算法(代码实例)<hash表的特性>Hash 表是使⽤ O(1) 时间进⾏数据的插⼊删除和查找,但是 hash 表不保证表中数据的有序性,这样在 hash 表中查找最或者最⼩数据的时间是 O(N) 。
<寻址和 hash 函数>理想状态下 hash ⾜够⼤,每⼀数据保存在⼀个 hash 存储单元内,这样对于插⼊删除和查找某⼀个数据就可以直接得到。
但是现实情况下 hash 表不可能⽆限⼤,⽽且理论上保存的数据的个数是没有限制的,这样保存的数据的数量就远远⼤于 hash 表的存储单元的数量。
为了实现在 O(1) 内对数据进⾏插⼊删除和查找,就必须将⼀个数据映射到 hash 表中的固定位置,这个映射函数就是 hash 函数。
Hash 函数通过对数据进⾏计算得到⼀个在 hash 表中的位置地址。
图 1.1 理想的 hash 表要选择较好的 hash 函数,以及 hash 表存储单元的数量,这样才能使保存在 hash 表中的数据均匀分布。
理想状态不太可能实现,由于存储的数据数量远远⼤于 hash 表存储单元的数量,所以再好的 hash 函数也可能使不同的数据得到相同的映射位置,这就造成了冲突。
但是好的 hash 函数可以将这种冲突降到最低。
<分离链接>解决这种冲突的第⼀种⽅法是借助链表来实现,就是将数据实际存放在与 hash 表存储单元相链接的链表中,⽽不是 hash 的存储单元中。
图 2.1 分离链表当产⽣冲突的时候,将两个数据都链接在同⼀ hash 存储单元保存的链表中。
当⼀个存储单元保存的链表中有多个数据的时候,对于链表后⾯的数据的查找添加和删除就是不是严格意义上的 O(1) 了。
⼀个好的 hash 函数可以使得这个链表很短。
最坏情况下,当所有的数据都保存在⼀个 hash 单元指定的链表中的时候,那么这个 hash 就和链表⼀样了。
<开放地址>使⽤开放地址⽅法解决冲突的时候,数据仍然保存在 hash 表的存储单元中,但是当冲突发⽣的时候,要再次计算新的地址。
c语言调用哈希算法
在C语言中,可以使用哈希算法来生成固定长度的哈希值,用于快速比较、存储和检索数据。
常用的哈希算法有MD5、SHA-1、SHA-256等。
下面是一个简单的示例代码,演示如何使用C语言调用哈希算法。
```c#include <stdio.h>#include <string.h>#include <openssl/sha.h>int main() {char *str = "Hello, world!";unsigned char hash[SHA256_DIGEST_LENGTH];// 调用SHA-256哈希算法生成哈希值SHA256_CTX sha256;SHA256_Init(&sha256);SHA256_Update(&sha256, str, strlen(str));SHA256_Final(hash, &sha256);// 输出哈希值printf("Hash value: ");for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {printf("%02x", hash[i]);}printf("\n");return 0;}```在上面的代码中,我们使用了OpenSSL库中的SHA256哈希算法。
首先定义了一个字符串`str`,然后声明了一个长度为SHA256_DIGEST_LENGTH的哈希值数组`hash`,用于存储生成的哈希值。
接着,我们初始化了一个SHA256上下文`sha256`,并使用`SHA256_Update`函数将要哈希的数据传送给算法引擎进行哈希运算。
最后,使用`SHA256_Final`函数将哈希结果保存到`hash`数组中。
最后,我们使用`printf`函数输出生成的哈希值。
c语言hashmap 查找方法
c语言hashmap 查找方法
在C语言中,实现哈希表(hashmap)的查找方法通常需要经历
以下步骤:
1. 哈希函数设计,首先,你需要设计一个哈希函数,它能够将
输入的键(key)映射到哈希表中的一个位置。
一个好的哈希函数应
该能够尽可能地均匀地将键映射到不同的位置,以减少冲突的发生。
2. 冲突处理,由于哈希函数的映射可能会导致不同的键映射到
同一个位置,因此需要一种方法来处理这种冲突。
常见的冲突处理
方法包括链地址法和开放寻址法。
在C语言中,你需要根据具体情
况选择合适的冲突处理方法,并实现相应的逻辑。
3. 查找操作:一旦哈希表中的数据经过哈希函数映射并存储起来,你就可以通过键来查找对应的数值。
在C语言中,通常可以通
过以下步骤来实现查找操作:
使用哈希函数计算键对应的哈希值。
根据哈希值找到对应的存储位置。
如果使用链地址法,需要遍历对应位置的链表来查找键;如果使用开放寻址法,需要根据特定的规则来寻找下一个位置,直到找到对应的键或者确定该键不存在。
4. 错误处理,在实现查找方法时,需要考虑键可能不存在的情况,因此需要实现相应的错误处理逻辑,以便在查找失败时能够返回适当的错误信息或者值。
总的来说,实现C语言中哈希表的查找方法需要考虑哈希函数设计、冲突处理、具体的查找逻辑以及错误处理。
这些步骤需要根据具体的应用场景和数据特点来进行合理的设计和实现。
希望这些信息能够帮助到你理解C语言中哈希表的查找方法。
C语言中的哈希表算法实现
C语言中的哈希表算法实现哈希表是一种常用的数据结构,它能够快速地存储和检索键值对。
在C语言中,哈希表的实现可以通过使用哈希函数将键映射为索引,再将键值对存储在相应的索引位置上。
本文将介绍C语言中哈希表算法的实现原理及相应的代码示例。
一、哈希函数的选择哈希函数是哈希表算法的核心,它将键映射为哈希值。
合适的哈希函数应具备以下特点:1. 高效性:哈希函数的计算速度应尽可能快速,以保证整个哈希表的性能;2. 均匀性:哈希函数的输出应均匀分布,避免过多的冲突;3. 独立性:哈希函数的输出应与键值的顺序和大小无关。
通常,常见的哈希函数包括除法取余法、乘法散列法和位运算法等。
下面以除法取余法为例,介绍哈希函数的实现。
```cunsigned int hash_function(int key, int size) {return key % size;}```二、哈希表的实现在C语言中,哈希表通常使用数组和链表结合的方式来实现。
每个数组元素对应一个链表,用于存储哈希冲突时的键值对。
首先,我们需要定义哈希表的结构。
其中包括哈希表的大小、数组指针和链表结构等。
```c#define TABLE_SIZE 100typedef struct Node {int key;int value;struct Node* next;} Node;typedef struct HashTable {Node* array[TABLE_SIZE];} HashTable;```接下来,我们需要实现初始化哈希表、插入键值对、删除键值对和查找键值对等基本操作。
1. 初始化哈希表```cHashTable* create_hash_table() {HashTable* hash_table = (HashTable*)malloc(sizeof(HashTable)); for (int i = 0; i < TABLE_SIZE; i++) {hash_table->array[i] = NULL;}return hash_table;}```2. 插入键值对```cvoid insert(HashTable* hash_table, int key, int value) {unsigned int index = hash_function(key, TABLE_SIZE);Node* new_node = (Node*)malloc(sizeof(Node));new_node->key = key;new_node->value = value;new_node->next = NULL;if (hash_table->array[index] == NULL) {hash_table->array[index] = new_node;} else {Node* curr = hash_table->array[index];while (curr->next != NULL) {curr = curr->next;}curr->next = new_node;}}```3. 删除键值对```cvoid delete(HashTable* hash_table, int key) {unsigned int index = hash_function(key, TABLE_SIZE); Node* curr = hash_table->array[index];Node* prev = NULL;while (curr != NULL && curr->key != key) {prev = curr;curr = curr->next;}if (curr == NULL) {return;}if (prev == NULL) {hash_table->array[index] = curr->next;} else {prev->next = curr->next;}free(curr);}```4. 查找键值对```cint find(HashTable* hash_table, int key) {unsigned int index = hash_function(key, TABLE_SIZE); Node* curr = hash_table->array[index];while (curr != NULL) {if (curr->key == key) {return curr->value;}curr = curr->next;}return -1;}```三、总结本文介绍了C语言中哈希表算法的实现原理及相应的代码示例。
c#哈希算法的实现方法及思路
c#哈希算法的实现⽅法及思路有想过hash["A1"] = DateTime.Now;这句是怎么实现的吗?我们来重温下学校时代就学过的哈希算法吧。
我们要写个class,实现如下主程序调⽤:复制代码代码如下:static void Main(string[] args){MyHash hash = new MyHash();hash["A1"] = DateTime.Now;hash["A2"] = 1;Console.WriteLine(Convert.ToString(hash["A1"]));Console.WriteLine(Convert.ToString(hash["A2"]));}⼀看,也确实挺简单的,就是⼀个所引器,如下:复制代码代码如下:class MyHash{public object this[string key]{get{}set{}}}程序中要保存的对象,最终是要保存在⼀个数组中的,⽽且需要通过⼀个转换函数来进⾏string key与数组Index的Map,如下:复制代码代码如下:private List<List<Tuple<string, object>>> lstArray = new List<List<Tuple<string, object>>>(defaultSize);private int MapString2Int(string key){int hashIndex=0;char[] keyAry = key.ToCharArray();foreach (var c in keyAry)hashIndex += (int)c;hashIndex = hashIndex % lstArray.Capacity;return hashIndex;}这个函数是遍历string key的每个char,累加,最终取模(同数组的长度),这样得出的⼀个value肯定就在数组范围内。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
哈希查找算法的源代码 c语言【问题描述】针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
[基本要求]假设人名为中国姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构照,用链表法处理冲突。
[测试数据]读取熟悉的30个人的姓名。
#include <fstream>#include <iostream>#include <cmath>using namespace std;#define Maxsize 57struct record{ char name[20];char tel[20];char add[20];};typedef record * precord;struct HashTable{ int elem[Maxsize]; //存放数组a[]的下标int count;};typedef HashTable * pHashTable;int Number; //统计当前数组a[]中的记录总数void Getdata(precord a) //从文件telphone.txt中读取数据存放到数组a[] { Number=0;ifstream infile("telphone.txt",ios::in|ios::binary);if(!infile) {cout<<"文件打开失败!\n"; exit(1);}while(!infile.eof() && infile.get()!=EOF) //文件不为空并且文件指针没有指到结束符{infile.seekg(Number*sizeof(a[Number]),ios::beg); //定位文件指针infile.read((char *)&a[Number],sizeof(a[Number]));Number++;}infile.close();}void Add(precord a) //添加记录{ int i,num;cout<<"当前文件内已有"<<Number<<"条记录\n";cout<<"请输入添加的个数:";cin>>num;ofstream ofile("telphone.txt",ios::app);if(! ofile) {cout<<"文件打开失败!"; exit(1);}for(i=0;i<num;i++){ cout<<"请输入第"<<Number+1<<"个人的姓名"<<endl; cin>>a[Number].name;cout<<"请输入第"<<Number+1<<"个人的电话"<<endl; cin>>a[Number].tel;cout<<"请输入第"<<Number+1<<"个人的地址"<<endl; cin>>a[Number].add;ofile.seekp(ios::end);ofile.write((char *)&a[Number],sizeof(a[Number])); Number++;}ofile.close();}void Print(precord a) //显示所有记录{ int i;for(i=0;i<Number;i++){cout<<"第"<<i+1<<"个人的信息为:\n";cout<<" 姓名:"<<a[i].name<<endl;cout<<" 电话:"<<a[i].tel<<endl;cout<<" 地址:"<<a[i].add<<endl;}}int Hash(char str[]) //除留取余{ long val=0;char p[20],*p1;strcpy(p,str);p1=p;while(*p1!='\0')val=val+*p1++; //将字符串中的所有字符对应的ASCII值相加return(val%Maxsize);}int derter; //线性增量int Line_Sollution(int address) //采用线性探测解决冲突{derter++;if(derter==Maxsize) return(-1);else return((address+derter)%Maxsize);}int n;int Square_Sollution(int address) //采用平方探测法解决冲突{ int j;derter++;if(derter==Maxsize) return -1;n=n*(-1);j=(int(pow(derter,2))*n+address)%Maxsize;return(j);}void Init_Hash(pHashTable h) //初始化哈希表{ int i;for(i=0;i<Maxsize;i++)h->elem[i]=-1;}int menu;void Creathash_Name(pHashTable h,precord a)//以用户名为关键字创建哈希表{ cout<<"--------------------------------------------------------------------------------\n";cout<<" 1----以线性探测建表\n";cout<<" 2----以平方探测建表\n";cout<<"--------------------------------------------------------------------------------\n";int i,address;cin>>menu;Init_Hash(h);for(i=0;i<Number;i++){ derter=0;n=-1;address=Hash(a[i].name);while(h->elem[address]!=-1){if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);if(address==-1) break;}if(address!=-1) { h->elem[address]=i; h->count++;}}cout<<"姓名哈希表已成功建立!\n";}void Search_Name(pHashTable h,precord a) //查找并显示指定姓名的记录{ cout<<"请输入要查找的姓名:";char nam[20];int address,i=1;cin>>nam;address=Hash(nam);derter=0;n=-1;while(h->elem[address]!=-1 && strcmp(nam,a[h->elem[address]].name)!=0) { if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);i++;if(address==-1) break;}if(h->elem[address]!=-1 && strcmp(nam,a[h->elem[address]].name)==0) { cout<<"你要查找的信息为:\n";cout<<" 姓名:"<<a[h->elem[address]].name<<endl;cout<<" 电话:"<<a[h->elem[address]].tel<<endl;cout<<" 地址:"<<a[h->elem[address]].add<<endl;cout<<"比较次数为"<<i<<endl;}else cout<<"无此姓名,查找失败!";}void Creathash_tel(pHashTable h,precord a)//以电话号为关键字创建哈希表{ cout<<"--------------------------------------------------------------------------------\n";cout<<" 1----以线性探测建表\n";cout<<" 2----以平方探测建表\n";cout<<"--------------------------------------------------------------------------------\n";int i,address;cin>>menu;Init_Hash(h);for(i=0;i<Number;i++){ derter=0;n=-1;address=Hash(a[i].tel);while(h->elem[address]!=-1){if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);if(address==-1) break;}if(address!=-1) { h->elem[address]=i; h->count++;}}cout<<"电话号哈希表已成功建立!\n";}void Search_tel(pHashTable h,precord a)//查找并显示指定电话号的记录{ cout<<"请输入要查找的电话:";char telphone[20];int address,i=1; //i统计比较次数cin>>telphone;address=Hash(telphone);derter=0; n=-1; //初始化线性增量while(h->elem[address]!=-1 && strcmp(telphone,a[h->elem[address]].tel)!=0){ if(menu==1) address=Line_Sollution(address);else address=Square_Sollution(address);i++;if(address==-1) break;}if(h->elem[address]!=-1 && strcmp(telphone,a[h->elem[address]].tel)==0) { cout<<"你要查找的信息为:\n";cout<<" 姓名:"<<a[h->elem[address]].name<<endl;cout<<" 电话:"<<a[h->elem[address]].tel<<endl;cout<<" 地址:"<<a[h->elem[address]].add<<endl;cout<<"比较次数为"<<i<<endl;}else cout<<"无此电话,查找失败!";}void Menu() //功能菜单函数{for(int i=1;i<=5;i++)cout<<endl;cout<<" 电话号码查询系统\n";cout<<'\n';cout<<" ★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆\n";cout<<" ☆ 0-------退出★\n";cout<<" ★ 1-------添加☆\n";cout<<" ☆ 2-------显示所有★\n";cout<<" ★ 3-------以性命建立哈希表☆\n";cout<<" ☆ 4-------以电话建立哈希表★\n";cout<<" ★ 5-------按用户名查找☆\n";cout<<" ☆ 6-------按电话号查找★\n";cout<<" ☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★\n"; cout<<" 使用说明:\n";cout<<" 1.添加新纪录后,如要进行查找请先进行3或4操作\n";cout<<" 2.按用户名查找之前,请先进行3操作建立用户名哈希表\n";cout<<" 3.按用户名查找之前,请先进行4操作建立电话号哈希表\n";}void exit(){int i;for(i=1;i<=4;i++)cout<<endl;cout<<" ◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◇◆◇\n"; cout<<" ◆ ◆\n";cout<<" ◇ 电话号码查询系统◇\n";cout<<" ◆ ◆\n";cout<<" ◇ 谢谢您的使用! ◇\n";cout<<" ◆ ◆\n";cout<<"◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇\n";}int main(){ record a[Maxsize];pHashTable H=new HashTable;Getdata(a); //将文件中的数据读入到数组a中start:Menu();int menu1;cin>>menu1;switch(menu1){ case 0:system("cls");exit();break;case 1:Add(a);system("pause");system("cls");goto start;break;case 2:Print(a);system("pause");system("cls");goto start;break;case 3:Creathash_Name(H,a);system("pause");system("cls");goto start;break;case 4:Creathash_tel(H,a);system("pause");system("cls");goto start;break;case 5:Search_Name(H,a);system("pause");system("cls");goto start;break;case 6:Search_tel(H,a);system("pause");system("cls");goto start;break;default:cout<<"请输入正确的操作选项!\n";system("cls");goto start;break;} return 0; }。