//проверка наличия элемента. был вариант возвращать элемент, но я решила передавать его как out аргумент public bool Search(int _key, out hashItem _item) { int hF = hashFunction1(_key); if (!isEmpty()) { //как только ячейка станет unengaged, это будет означать, что дальше нужной ячейки точно не будет (больше нет коллизий) //поэтому пока ячейка заполнена и не подходит ИЛИ удалена, применяем хеш функцию while ((table[hF].getStatus() == Status.engaged && table[hF].getNumber() != _key) || (table[hF].getStatus() == Status.deleted)) //если первый хеш не подошел, применяем второй { hF = (hF + hashFunction2(_key)) % size; } //в итоге мы остановимся либо на заполненной ячейке с подходящим ключом, либо на unengaged if (table[hF].getStatus() == Status.engaged) //если ячейка, на которой остановились, заполнена, то в ней точно нужный ключ { _item = new hashItem(); _item = table[hF]; return(true); } //иначе она unengaged, т е элемента с таким ключом не существует else { _item = null; return(false); } } _item = null; Console.WriteLine("Warning: the table is empty."); return(false); }
//удаление элемента public void Delete(int key) { hashItem _item = new hashItem(); if (Search(key, out _item)) //если такой элемент в таблице существует, то применяем первый хеш { int hF = hashFunction1(key); if (!isEmpty()) { //если первый хеш не подошел (ячейка пуста/не совпал номер), применяем второй (пока не найдем нужную) while (table[hF].getStatus() != Status.engaged || table[hF].getNumber() != key) { hF = (hF + hashFunction2(key)) % size; } //когда мы выходим из while, элемент точно найден //тк в самом начале Delete есть проверка на его существование в таблице (если бы его не было, в этот цикл не вошли бы) table[hF].setDeleted(); //меняем статус на "удалена" --count; Console.WriteLine("User record was removed successfully."); } //иначе выводим предупреждение else { Console.WriteLine("Warning: unable to remove user record. The table is empty."); } } else { Console.WriteLine("Warning: user with number #" + key + " does not exist"); } }
//добавление элемента public void Add(hashItem _item) { bool ok = true; int key = _item.getNumber(); //запоминаем ключ (таб. номер) int hF = hashFunction1(key); if (!isFull()) //если таблица не полная, то пытаемся добавить { while (table[hF].getStatus() == Status.engaged && ok) //если по первому хешу уже что-то лежит, применяем второй, пока не дойдем до пустой ячейки или конца таблицы { ok = table[hF].getNumber() != key; // hF = (hF + hashFunction2(key)) % size; } if (table[hF].getStatus() != Status.engaged && ok) //если статуc ячейки == не занята или удалена, то добавляем элемент { table[hF].setEngaged(); table[hF].setInfo(_item); ++count; } else { Console.WriteLine("Warning: user numbers can not be equal."); } } //иначе оповещаем юзера о невозможности добавления else { Console.WriteLine("Warning: unable to add user record. The table is full."); } }
//перегрузка, копирование другого hashItem'а public void setInfo(hashItem _item) { setEngaged(); setNumber(_item.getNumber()); setNSP(_item.getNSP()); setPayment(_item.getPayment()); }
public int count; //к-во эл. в таблице //конструктор public hashTable() { for (int i = 0; i < size; ++i) { table[i] = new hashItem(); //теперь все ячейки считаются незанятыми } count = 0; //число занятых == 0 }
public void Task(int _number) { hashItem item; if (_number < 1) { Console.WriteLine("Warning: the number must be positive"); } else { item = new hashItem(); if (Search(_number, out item)) { Console.WriteLine(item.getInfo()); } else { Console.WriteLine("Warning: cannot find the user #" + _number); } } }
//загрузка из файла public void loadFrom() { string line; hashItem item = new hashItem(); try { //каждую строку файла передаем в соответствующий метод set для строки using (StreamReader sr = new StreamReader("TestFile.txt")) { while ((line = sr.ReadLine()) != null) { item.setInfo(line); Add(item); } } } catch (IOException e) { Console.WriteLine("Warning: unable to read the file."); Console.WriteLine(e.Message); } }
static void Main(string[] args) { hashTable hash = new hashTable(); bool quit = false; bool full = false; //проверка, пустая ли таблица (можно ли в ней что-то искать) string c = ""; while (!quit) { menu(); int code; c = Console.ReadLine(); switch (c) { case "0": quit = true; break; case "1": hash.loadFrom(); hash.Print(); full = true; Console.WriteLine(); Console.WriteLine(); break; case "2": Console.WriteLine(); if (full) { Console.WriteLine("Please, enter the number."); if (int.TryParse(Console.ReadLine(), out code)) { hash.Task(code); } } else { Console.WriteLine("Warning: the table is empty."); } Console.WriteLine(); Console.WriteLine(); break; case "3": hash.Clear(); full = false; Console.WriteLine(); Console.WriteLine(); break; case "4": Console.WriteLine("Please, enter the number."); hashItem item = new hashItem(); if (int.TryParse(Console.ReadLine(), out code)) { hash.Delete(code); } break; default: Console.WriteLine("Warning: cannot interpret command. Try again."); Console.WriteLine(); Console.WriteLine(); break; } } }