Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Collections;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace MyHashTable
- {
- public class OpenAddressHashTable<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>, IHashTable<TKey, TValue> where TKey : IEquatable<TKey>
- {
- Pair<TKey, TValue>[] _table;
- private int _capacity;
- HashMaker<TKey> _hashMaker1, _hashMaker2;
- public int Count { get; private set; }
- private const double FillFactor = 0.71;
- private readonly GetPrimeNumber _primeNumber = new GetPrimeNumber();
- public OpenAddressHashTable()
- {
- _capacity = _primeNumber.GetMin();
- _table = new Pair<TKey, TValue>[_capacity];
- _hashMaker1 = new HashMaker<TKey>(_capacity);
- _hashMaker2 = new HashMaker<TKey>(_capacity - 1);
- Count = 0;
- }
- public OpenAddressHashTable(int m)
- {
- _table = new Pair<TKey, TValue>[m];
- _capacity = m;
- _hashMaker1 = new HashMaker<TKey>(_capacity);
- _hashMaker2 = new HashMaker<TKey>(_capacity - 1);
- Count = 0;
- }
- public void Add(TKey key, TValue value)
- {
- var hash = _hashMaker1.ReturnHash(key);
- if (!TryToPut(hash, key, value)) // ячейка занята
- {
- int iterationNumber = 1;
- while (true)
- {
- var place = (hash + iterationNumber * (1 + _hashMaker2.ReturnHash(key))) % _capacity;//(1 + _hashMaker2.ReturnHash(key))
- if (TryToPut(place, key, value))
- break;
- iterationNumber++;
- if (iterationNumber >= _capacity)
- throw new ApplicationException("HashTable full!!!");
- }
- }
- if ((double)Count / _capacity >= FillFactor)
- {
- IncreaseTable();
- }
- }
- public void Delete(TKey key)
- {
- Pair<TKey, TValue> pair = Find(key);
- if(pair != null)
- {
- pair.DeletePair();
- }
- }
- private bool TryToPut(int place, TKey key, TValue value)
- {
- if (_table[place] == null || _table[place].IsDeleted())
- {
- _table[place] = new Pair<TKey, TValue>(key, value);
- Count++;
- return true;
- }
- if (_table[place].Key.Equals(key))
- {
- throw new ArgumentException();
- }
- return false;
- }
- private Pair<TKey, TValue> Find(TKey x)
- {
- var hash = _hashMaker1.ReturnHash(x);
- if (_table[hash] == null)
- return null;
- if (!_table[hash].IsDeleted() && _table[hash].Key.Equals(x))
- {
- return _table[hash];
- }
- int iterationNumber = 1;
- while (true)
- {
- var place = (hash + iterationNumber * (1 + _hashMaker2.ReturnHash(x))) % _capacity;
- if (_table[place] == null)
- return null;
- if (!_table[place].IsDeleted() && _table[place].Key.Equals(x))
- {
- return _table[place];
- }
- iterationNumber++;
- if (iterationNumber >= _capacity)
- return null;
- }
- }
- public TValue this[TKey key]
- {
- get
- {
- var pair = Find(key);
- if (pair == null)
- throw new KeyNotFoundException();
- return pair.Value;
- }
- set
- {
- var pair = Find(key);
- if (pair == null)
- throw new KeyNotFoundException();
- pair.Value = value;
- }
- }
- private void IncreaseTable()
- {
- //получить число и увеличить таблицу
- int m = _primeNumber.Next();
- Pair<TKey, TValue>[] newTable = _table;
- _table = new Pair<TKey, TValue>[m];
- _capacity = m;
- _hashMaker1.SimpleNumber = _capacity;
- _hashMaker2.SimpleNumber = _capacity - 1;
- Count = 0;
- foreach (var pair in newTable)
- {
- if (pair != null)
- Add(pair.Key, pair.Value);
- }
- //int size = _primeNumber.Next();
- //_hashMaker1.SimpleNumber = size;
- //_hashMaker2.SimpleNumber = size - 1;
- //_capacity = size;
- //var tableItem = _table;
- //_table = new Pair<TKey, TValue>[size];
- //Count = 0;
- //foreach(var pair in tableItem)
- //{
- // if(pair != null)
- // Add(pair.Key, pair.Value);
- //}
- }
- public bool ContainsKey(TKey key)
- {
- return Find(key) != null;
- }
- public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
- {
- return (from pair in _table where pair != null && !pair.IsDeleted() select new KeyValuePair<TKey, TValue>(pair.Key, pair.Value)).GetEnumerator();
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement