/* * IA_11.2ChainedHash.cpp * * Created on: Feb 12, 2015 * Author: sunyj */ #include <stdint.h> #include <iostream> #include <string.h> // CHAINED-HASH-INSERT(T, x) // insert x at the head of list T[h(x.key)] // CHAINED-HASH-SEARCH(T, k) // search for an element with key k in list T[h(k)] // CHAINED-HASH-DELETE(T, x) // delete x from the list T[h(x.key)] class ListNode { public: ListNode() : key(0), data(0), prev(nullptr), next(nullptr) { std::cout << "ListNode()" << std::endl; } ListNode(int64_t const k, int64_t d) : key(k), data(d), prev(nullptr), next(nullptr) { } int64_t key; int64_t data; ListNode* prev; ListNode* next; }; // LIST-SEARCH(L, k) // x = L.nil.next // while ( x != L.nil and x.key != k) // x = x.next // return x // LIST-INSERT(L, x) // x.next = L.nil.next // L.nil.next.prev = x // L.nil.next = x // x.prev = L.nil // LIST-DELETE(L, x) // x.prev.next = x.next // x.next.prev = x.prev class LinkedList { public: LinkedList() : nil(&m_nil) { std::cout << "LinkedList()" << std::endl; nil->prev = nil; nil->next = nil; nil->data = -1; // } ListNode* search(int64_t const k) { ListNode* x = nil->next; while (x != nil && k != x->key) { x = x->next; } return x; } void insert(ListNode* x) { x->next = nil->next; nil->next->prev = x; nil->next = x; x->prev = nil; } void del(ListNode* x) { x->prev->next = x->next; x->next->prev = x->prev; } void print() { ListNode* x = nil->next; while (nil != x) { std::cout << x->key << " "; x = x->next; } std::cout << std::endl; } private: ListNode m_nil; // empty list has noe node, pointer nill points to it. ListNode* nil; }; class ChainedHashTable { public: ChainedHashTable(int64_t const n) : size(n) { data = new LinkedList[n](); } ~ChainedHashTable() {} int64_t HashFunc(int64_t const key) { return key % size; } ListNode* search(int64_t const key) { return data[HashFunc(key)].search(key); } void insert(ListNode* x) { (data[HashFunc(x->key)]).insert(x); } void del(ListNode* x) { data[HashFunc(x->key)].del(x); } void print(int64_t key) { data[HashFunc(key)].print(); } private: LinkedList* data; int64_t size; }; int main() { LinkedList a; /* * A prime not too close to an exact power of 2 is often a good choice for m. For example, suppose we wish to allocate a hash table, with collisions resolved by chaining, to hold roughly n = 2000 character strings, where a character has 8 bits. We don‘t mind examining an average of 3 elements in an unsuccessful search, and so we allocate a hash table of size m = 701. We could choose 701 because it is a prime near 2000=3 but not near any power of 2. */ ChainedHashTable table(701); // The division method, ListNode node1(1, 100); ListNode node4(4, 400); ListNode node16(16, 1600); ListNode node9(9, 900); table.insert(&node1); table.insert(&node4); table.insert(&node16); table.insert(&node9); table.print(4); ListNode node25(25, 2500); table.insert(&node25); table.print(16); table.del(&node1); table.print(9); ListNode* tmp; tmp = table.search(9); table.del(tmp); table.print(9); return 0; }
时间: 2024-10-10 02:37:36