实现说明
线程不安全; 2倍扩容,方便使用位运算计算桶位置;但存在极端情况下的弊端; 不支持将链表转为红黑树
源码
#pragma once
#include <string>
int Hash ( int key) {
return key;
}
class HashMap {
class Node {
public :
const int key;
int val;
const int hash;
Node* next = NULL ;
Node ( int hash, int key, int val) : hash ( hash) , key ( key) , val ( val) {
}
Node* findNode ( const int & key) {
Node* node = this ;
while ( node != NULL && node- > key != key)
node = node- > next;
return node;
}
} ;
using NodePtr = Node* ;
NodePtr* table;
const double load_factor = 0.75 ;
int threshold = 12 ;
int size = 1 << 4 ;
int maxSize = 1 << 30 ;
int count = 0 ;
void resize ( ) {
if ( size >= maxSize) return ;
int newSize = size << 1 ;
NodePtr* newTable = new NodePtr[ newSize] ;
memset ( newTable, 0 , newSize * sizeof ( NodePtr) ) ;
for ( int i = 0 ; i < size; ++ i) {
Node* node = table[ i] ;
while ( node != NULL ) {
int index = node- > hash & ( newSize - 1 ) ;
Node* tmp = node- > next;
node- > next = newTable[ index] ;
newTable[ index] = node;
node = tmp;
}
}
std:: swap ( newTable, table) ;
size = newSize;
threshold = size * load_factor;
delete [ ] newTable;
}
void addCount ( int x) {
count + = x;
if ( count > threshold)
resize ( ) ;
}
public :
HashMap ( ) {
table = new NodePtr[ size] ;
memset ( table, 0 , size * sizeof ( NodePtr) ) ;
}
~ HashMap ( ) {
for ( int i = 0 ; i < size; ++ i) {
Node* node = table[ i] ;
while ( node != NULL ) {
Node* tmp = node- > next;
delete node;
node = tmp;
}
table[ i] = NULL ;
}
delete [ ] table;
}
HashMap ( const HashMap& ) = delete ;
HashMap& operator = ( const HashMap& ) = delete ;
bool get ( int key, int & value) {
int hash = Hash ( key) ;
Node* node = NULL ;
int index = hash & ( size - 1 ) ;
if ( table[ index] != NULL )
node = table[ index] - > findNode ( key) ;
if ( node != NULL ) value = node- > val;
return node != NULL ;
}
void put ( int key, int value) {
int hash = Hash ( key) ;
Node* node = NULL ;
int index = hash & ( size - 1 ) ;
if ( table[ index] != NULL )
node = table[ index] - > findNode ( key) ;
if ( node != NULL ) node- > val = value;
else {
node = new Node ( hash, key, value) ;
node- > next = table[ index] ;
table[ index] = node;
addCount ( 1 ) ;
}
}
} ;