哈希表转换

时间:2018-03-11 11:08:16

标签: c# hashmap hashtable

我有一个不常见的问题/请求。我正在学习哈希表,并且在使用方形哈希函数时有一个带开放寻址的哈希表,而我正在试图弄清楚如何将它转换为带有列表的哈希表?可以从提供的代码中做到吗?对不起,如果问题太广泛或不清楚,请尝试学习: `

class HMap<K, V>
    {
        public static int DEFAULT_INITIAL_CAPACITY = 16;
        public static float DEFAULT_LOAD_FACTOR = 0.75f;

        Entry<K, V>[] table;

        protected int size = 0;

        protected float loadFactor;

        protected int rehashesCounter = 0;

        protected int index;

        public HMap()
        {
            loadFactor = DEFAULT_LOAD_FACTOR;
            this.table = new Entry<K, V>[DEFAULT_INITIAL_CAPACITY];

        }

        public HMap(int initialCapacity)
        {
            loadFactor = 0.75F;
            this.table = new Entry<K, V>[initialCapacity];
        }

        public Boolean IsEmpty()
        {
            return size == 0;
        }

        public int Size()
        {
            return size;
        }

        public void Clear()
        {
            for(int i = 0; i < table.Length; i++)
            {
                table[i] = null;
            }
            size = 0;
            rehashesCounter = 0;
        }

        public V Put(K key, V value)
        {
            if (key == null || value == null)
            {
                throw new Exception("Key or value is null in put(Key key, Value value)");
            }
            index = FindPosition(key);
            if (index == -1)
            {
                return default(V);
            }
            table[index] = new Entry<K, V>(key, value);

            size++;
            if (size > table.Length * loadFactor)
            {
                Rehash(table[index]);
            }
            return value;
        }

        public V Get(K key)
        {
            if (key == null)
            {
                throw new Exception("Key is null in get(Key key)");
            }

            index = FindPosition(key);
            return (table[index] != null) ? table[index].value : default(V);
        }

        public Boolean Contains(K key)
        {
            return Get(key) != null;
        }

        public Boolean ContainsValue(V value)
        {
            foreach (Entry<K, V> e in table)
            {
                if (e != null)
                {
                    if (e.value.Equals(value))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private void Rehash(Entry<K, V> entry)
        {
            HMap<K, V> map = new HMap<K, V>(table.Length * 2);
            for (int i = 0; i < table.Length; i++)
            {
                if (table[i] != null)
                {
                    map.Put(table[i].key, table[i].value);
                }

            }
            table = map.table;
            rehashesCounter++;
        }

        private int Hash(K key)
        {
            int h = key.GetHashCode();
            return Math.Abs(h) % table.Length;
        }

        private int FindPosition(K key)
        {
            index = Hash(key);
            int indexO = index;
            int i = 0;
            for (int j = 0; j < table.Length; j++)
            {
                if (table[index] == null || table[index].key.Equals(key))
                {
                    return index;
                }
                i++;
                index = (indexO + i * Hash2(key)) % table.Length;
            }
            return -1;
        }

        private int Hash2(K key)
        {
            return 7 - (Math.Abs(key.GetHashCode()) % 7);
        }

        public override String ToString()
        {
            StringBuilder result = new StringBuilder();
            foreach (Entry<K, V> entry in table)
            {
                if (entry == null)
                {
                    result.Append("null").Append("\n");
                }
                else
                {
                    result.Append(entry.toString()).Append("\n");
                }
            }
            return result.ToString();
        }

        public void ToFile(string fileName)
        {
            using(StreamWriter file = new StreamWriter(@fileName))
            {
                foreach (Entry<K, V> entry in table)
                {
                    if (entry == null)
                    {
                        file.WriteLine("null");
                    }
                    else
                    {
                        file.WriteLine(entry.toString());
                    }
                }
            }
        }

        class Entry<Key, Value>
        {

            public Key key;
            public Value value;

            public Entry(Key key, Value value)
            {
                this.key = key;
                this.value = value;
            }

            public String toString()
            {
                return key + "=" + value;
            }

        }
    }

`

0 个答案:

没有答案