해시 시계 (지퍼 법)
15112 단어 데이터 구조
산열 법: 먼저 관건 적 인 코드 집합 에 대해 산열 함수 로 산열 주 소 를 계산 하고 같은 주 소 를 가 진 관건 적 인 코드 는 같은 서브 집합 에 귀착 한다. 모든 서브 집합 을 하나의 통 이 라 고 하고 각 통 의 요 소 는 하나의 단일 체인 표를 통 해 연결 되 며 각 링크 의 머리 결점 은 하 쉬 표 에 저장 된다.요소 의 키 코드 는 37, 25, 14, 36, 49, 68, 57, 11 이 고 해시 표 는 HT [12] 이 며 표 의 크기 는 12 이 며 해시 함 수 는 Hash (x) = x% 11 Hash (37) = 4 Hash (25) = 3 Hash (36) = 3 Hash (49) = 5 Hash (68) = 2 Hash (11) = 0 해시 함 수 를 사용 하여 각 요소 가 있 는 통 번 호 를 계산 하고 같은 통 의 링크 에 해시 충돌 요 소 를 저장 합 니 다.일반적으로 모든 통 에 대응 하 는 링크 의 결산 점 이 매우 적 고 n 개의 관건 적 인 코드 를 특정한 해시 함 수 를 통 해 산 목록 에 있 는 m 개의 통 에 저장 하면 모든 통 에 있 는 링크 의 평균 길 이 는?검색 길이 가 n 인 순서 표를 검색 평균 길이 로 대체 하여 검색 효율 이 훨씬 빠르다.체인 주소 법 처리 가 넘 쳐 서 링크 지침 을 증설 해 야 합 니 다. 저장 비용 이 증가 한 것 같 습 니 다.사실: 주소 법 을 열 려 면 검색 효율 을 확보 하기 위해 대량의 빈 공간 을 유지 해 야 합 니 다. 예 를 들 어 2 차 탐사 법 은 인자 a < = 0.7 을 불 러 오 라 고 요구 하고 표 항목 이 차지 하 는 공간 은 포인터 보다 많 기 때문에 체인 주소 법 을 사용 하 는 것 이 주소 법 을 여 는 것 보다 저장 공간 을 절약 합 니 다.
산열 의 실현 (지퍼 법) HashNode. h
#pragma once
#include
#include
#include
typedef int KeyType;
typedef int valueType;
typedef struct HashNode
{
KeyType _key;
valueType _value;
struct HashNode*_next;
}HashNode;
typedef struct HashTable
{
HashNode** table;
size_t _size;
size_t _N;
}HashTable;
HashNode*BuyHashNode(KeyType key, valueType value);
size_t GetHashTablePrime(size_t N);
void HashTableInit(HashTable*ht,int size);//
void HashTablePrint(HashTable*ht);
int HashTableInsert(HashTable*ht, KeyType key, valueTypevalue);//
HashNode* HashTableFind(HashTable*ht, KeyType key);//
size_t HashTableErase(HashTable*ht, KeyType key);//
void HashTableDesTroy(HashTable*ht);//
HashNode.c
#include"HashNode.h"
HashNode* BuyHashNode(KeyType key, valueType value)
{
HashNode*Node = (HashNode*)malloc(sizeof(HashNode));
assert(Node);
Node->_key = key;
Node->_value = value;
Node->_next = NULL;
return Node;
}
void HashTableInit(HashTable*ht,int size)//
{
assert(ht);
ht->_size = 0;
ht->_N = size;
//
ht->table = (HashTable**)malloc(sizeof(HashTable*)*ht->_N);
assert(ht->table);
memset(ht->table, 0, sizeof(HashTable*)*ht->_N);
}
size_t GetHashTablePrime(size_t N)
{
static const unsigned long _PrimeList[28] =
{
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul
};
for (int i = 0; i < 28; i++)
{
if (N < _PrimeList[i])
{
N = _PrimeList[i];
return N;
}
}
return _PrimeList[27];
}
size_t HashFunc(KeyType key, size_t N)
{
return key%N;
}
int HashTableInsert(HashTable*ht, KeyType key, valueType value)//
{
assert(ht);
HashNode* node = BuyHashNode(key, value);
if (ht->_size * 10 / ht->_N > 7)
{
//
size_t newN = GetHashTablePrime(ht->_N);
HashTable newht;
HashTableInit(&newht, newN);
for (size_t i = 0; i < ht->_N; i++)
{
HashNode* cur = ht->table[i];//
if (ht->table[i])
{
size_t index = HashFunc(cur->_key, newht._N);//
while (cur)
{
cur->_next = newht.table[index];//
newht.table[index] = cur;//
cur = cur->_next;
}
}
}
free(ht->table);
ht->_N = newN;//
ht->table = newht.table;//
}
size_t index = HashFunc(key, ht->_N);
if (ht->table[index])
{
HashNode*cur = ht->table[index];
while (cur)
{
if (cur->_key == key)
{
return -1;
}
cur = cur->_next;
}
}
node->_next = ht->table[index];
ht->table[index] = node;
ht->_size++;
return 0;
}
void HashTablePrint(HashTable*ht)
{
for (size_t i = 0; i < ht->_N; i++)
{
if (ht->table[i])
{
HashNode*cur = ht->table[i];
while (cur)
{
printf("[%d]->%d
",i, cur->_key);
cur = cur->_next;
}
}
}
}
HashNode *HashTableFind(HashTable*ht, KeyType key)
{
assert(ht);
size_t index = HashFunc(key, ht->_N);
if (ht->table[index])
{
if (ht->table[index]->_key=key)
{
return ht->table[index];
}
else
{
HashNode*cur = ht->table[index];
while (cur)
{
if (cur->_key==key)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}
}
}
size_t HashTableErase(HashTable*ht, KeyType key)
{
assert(ht);
size_t index = HashFunc(key, ht->_N);
if (ht->table[index])
{
HashNode* cur = ht->table[index];
HashNode* prev = ht->table[index];
while (cur)
{
if (cur == prev&&cur->_key == key)//
{
ht->table[index] = cur->_next;
free(cur);
cur = NULL;
ht->_size--;
return 0;
}
else if (cur->_key == key)//
{
prev = cur->_next;
free(cur);
cur = NULL;
ht->_size--;
return 0;
}
prev = cur;
cur = cur->_next;
}
return -1;
}
else
{
return -1;
}
}
void HashTableDesTroy(HashTable*ht)
{
assert(ht);
for (size_t i = 0; i < ht->_N; i++)
{
if (ht->table[i])
{
HashNode*cur = ht->table[i];
while (cur)
{
HashNode*tmp = cur;
cur = cur->_next;
free(tmp);
tmp = NULL;
}
}
}
free(ht->table);
ht->table = NULL;
ht->_N = 0;
ht->_size = 0;
}
test.c
#include"HashNode.h"
void test()
{
HashTable ht;
HashTableInit(&ht,5);
HashTableInsert(&ht, 8,0);
HashTableInsert(&ht, 11, 0);
HashTableInsert(&ht, 10, 0);
HashTableInsert(&ht, 12, 0);
HashTableInsert(&ht, 2, 0);
HashTableInsert(&ht, 5, 0);
HashTableInsert(&ht, 20, 0);
HashTablePrint(&ht);
printf("
");
printf("%d
", HashTableFind(&ht, 10)->_key);
printf("%d
", HashTableFind(&ht, 12)->_key);
printf("%d
",HashTableFind(&ht, 20)->_key);
printf("%d
", HashTableFind(&ht, 8)->_key);
printf("%p
", HashTableFind(&ht, 1)->_key);
printf("
");
HashTableErase(&ht, 8);
HashTableErase(&ht, 2);
HashTableErase(&ht, 5);
HashTableErase(&ht, 20);
HashTablePrint(&ht);
printf("
");
HashTableDesTroy(&ht);
HashTablePrint(&ht);
}
int main()
{
test();
system("pause");
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.