#ifndef __LINKED_HASH_CPP #define __LINKED_HASH_CPP #include #include "dllist.hpp" #include "dictionary.hpp" #include "key_value_pair.hpp" template using HashFunction = unsigned (*)(K const&); template unsigned trivialHashFunction(K const& key) { return key; } template hashFunction = trivialHashFunction, size_t TABLE_SIZE = 100> class LinkedHashTable : public Dictionary { private: using KVP = KeyValuePair; using Bucket = DoubleLinkedList; using I = typename Bucket::I; Bucket table[TABLE_SIZE]; Bucket& findBucket(K const& key) { return table[hashFunction(key) % TABLE_SIZE]; } Bucket const& findBucket(K const& key) const { return table[hashFunction(key) % TABLE_SIZE]; } size_t count, buckets, collisions; public: LinkedHashTable() : count(0), buckets(0), collisions(0) {} // търсене на стойност по ключ V* lookup(K const& key) { Bucket& bucket = findBucket(key); I it = bucket.find(key); if (!it) return nullptr; return &(*it).value; } V const* lookup(K const& key) const { Bucket const& bucket = findBucket(key); I it = bucket.find(key); if (!it) return nullptr; return &(*it).value; } // свързване на ключ със стойност bool add(K const& key, V const& value) { Bucket& bucket = findBucket(key); I it = bucket.find(key); if (it) return false; count++; if (bucket.empty()) buckets++; else collisions++; return bucket.insertLast(KVP(key, value)); } // изтриване на стойност, свързана с ключ bool remove(K const& key) { Bucket& bucket = findBucket(key); I it = bucket.find(key); if (!it) return false; KVP tmp; count--; bucket.deleteAt(tmp, it); if (bucket.empty()) buckets--; else collisions--; return true; } // списък от ключове LinkedList keys() const { LinkedList result; for (Bucket const& bucket : table) for (KVP const& kvp : bucket) result.insertLast(kvp.key); return result; } // списък от стойности LinkedList values() const { LinkedList result; for (Bucket const& bucket : table) for (KVP const& kvp : bucket) result.insertLast(kvp.value); return result; } void info(std::ostream& os = std::clog) const { os << "елементи: " << count << ", кофи: " << buckets << ", колизии: " << collisions << std::endl; } }; #endif