| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Удаление узлов из бинарного дерева до даты, введен |
| Автор: Creder 9.5.2015, 15:05 | ||
| Здравствуйте. Такой вопрос. Используя классы, создать упорядоченное бинарное дерево, которое описывает справочник файлов в файловой системе. Каждому узлу соответствует некоторый файл , в узле содержится имя файла и дата последнего обращения к нему. Узлов в дереве не менее 15. Реализовать функцию, которая удаляет из дерева все файлы(узлы), обращение к которому было произведено до даты, введённой с клавиатуры. Исходное и результирующее дерево вывести на экран. Проблема заключается в создании функции удаления тех самых узлов. Не знаю, что делать. Помогите, пожалуйста.
|
| Автор: Creder 11.5.2015, 20:35 | ||
Я особо не силен в этом. Кое-что нашел в интернете. Подойдет ли это? И если да, то как модифицировать это под мое задание?
Здесь, вроде, соблюдаются все 3 условия удаления узла из дерева. |
| Автор: feodorv 11.5.2015, 21:07 |
За основу - да. Но очень много ошибок в найденном коде...
|
| Автор: Creder 14.5.2015, 10:06 | ||
А если попробовать как-то так?
|
| Автор: Creder 15.5.2015, 16:18 | ||
В общем, попытался сделать вот так, но компилятор выдает ошибки такого рода: |129|error: void value not ignored as it ought to be| |134|error: void value not ignored as it ought to be| |136|error: void value not ignored as it ought to be| |144|error: void value not ignored as it ought to be| Что не так? |
| Автор: feodorv 15.5.2015, 19:55 |
Функция removeNode не возвращает значения: поэтому присвоить чему-то возвращаемый результат работы функции (а его попросту нет) не удасться: |
| Автор: Creder 18.5.2015, 09:10 | ||
Теперь при создании дерева программа стала вылетать. Где ошибка? |
| Автор: feodorv 18.5.2015, 10:03 | ||||
Знакомое условие. В чем его смысл? Почему оно записано именно в таком дурацком виде? Девушка из http://forum.vingrad.ru/forum/topic-383329.html, в которой решена задача, аналогичной Вашей, по этому поводу написала так:
Ну посмотрите на то, как Вы вставляете новый узел в дерево:
|
| Автор: Creder 18.5.2015, 13:29 | ||||
Хорошо. Переписал. Но все равно вылетает ошибка. Что опять не так?
Может, где-то напортачил в самой функции добавления узла?
|
| Автор: feodorv 18.5.2015, 21:32 | ||
Хорошо, что создание узла Вы внесли в цикл добавления. Теперь у Вас добавляются разве экземпляры узла. Но данные для этого узла, вводимые с клавиатуры, до узла не доходят. Узел добавляется в дерево в отрыве от этих данных. Более того, конструктор по умолчанию у Node отсутствует, поля у вновь создаваемого Node остаются неинициализированными. В C++ есть же прекрасная возможность создания экземпляра класса сразу с инициализирующими значениями - конструктор класса. Почему Вы ей не пользуетесь?
Да. Отбросив тот факт, что Вы сравниваете неинициализированные данные (то есть мусор), http://forum.vingrad.ru/index.php?showtopic=383329&view=findpost&p=2639289, что по окончании цикла curr есть 0. Если потом делать curr->name, curr->left, curr->right, то это значит сознательный крах программы. |
| Автор: Creder 18.5.2015, 23:21 | ||||
Т. е. сначала, мне надо это
сделать, э-э-э, так или как-то иначе?
|
| Автор: feodorv 19.5.2015, 00:22 | ||||
Можно и так, но параметры-то конструктора должны же быть использованы для инициализации, да и left и right нужно занулить:
Если Вам не нравится такая форма конструктора, когда поля класса инициализируются до тела конструктора, а само тело конструктора пустое, используйте другой (пусть и худший) подход к конструктору:
Тогда все поля вновь создаваемого экземпляра класса будут правильно проинициализированы. PS Для имени файла при передаче конструктору используется ссылка и квалификатор const. PSS Имена аргументов конструктора изменены таким образом, чтобы они не совпадали с именами полей класса. |
| Автор: Creder 19.5.2015, 14:36 |
| Что же, с добавлением узла я все таки разобрался, но я все так же не могу понять, как удалять узел. Тем более в моем случае. Как быть? |
| Автор: feodorv 19.5.2015, 21:47 | ||
Гм. Простите мне мою лень, но второй раз описывать уже http://forum.vingrad.ru/index.php?showtopic=383329&view=findpost&p=2639249 не хочется. В соседней ветке всё есть, может не разжевано до конца, до очень много комментариев и пояснений, сделанных в том числе и для Вас. Вам только нужно изменить условие, при котором узел удаляется из дерева. |
| Автор: Creder 20.5.2015, 13:12 | ||||
Похоже, это подойдет.
Но правильно ли я ищу узлы?
|
| Автор: feodorv 21.5.2015, 03:33 |
Похоже или подойдёт? Вы ту тему до конца читали? Нет. Совершенно нет.
|
| Автор: Creder 21.5.2015, 15:11 | ||||||||
Насколько я понял, нужно создать логическую функцию проверки даты - передать в эту функцию записанную дату с клавиатуры и дату из узла и проверить их.
Затем результат этой проверки использовать в этих функциях: Здесь
и здесь
А затем нужный узел удалить!
|
| Автор: feodorv 21.5.2015, 22:28 | ||||||
Можно и так. Только прототип функции проверки будет таким:
Да! Но от while'ов лучше отказаться, сначала проверив левую и правые ветви узла, а уже затем сам узел на удовлетворение условию. А так же придётся таскать за собой параметры проверки day, month, year. |
| Автор: Creder 22.5.2015, 20:38 | ||
Извините. Не совсем понял. Можете по-подробнее объяснить? |
| Автор: feodorv 23.5.2015, 00:11 | ||
Ну, например:
|
| Автор: Creder 25.5.2015, 10:09 | ||
| Это же обратный обход дерева. Как я сразу не догадался? И последнее. Не могу разобраться с логической функцией. Мне приходит в голову только это:
|
| Автор: feodorv 25.5.2015, 16:42 | ||
Сама проверка даты в том виде, в котором она присутствует в коде, не представляет никакого труда. Сначала нужно проверить год узла. Если он больше года введённой с клавиатуры даты, то узел - свежий, удалять не надо. Если меньше, то узел устарел, нужно удалять. Проблема возникает только в случае равенства годов, в таком случае нужно проверить месяц узла. Если он больше месяца введённой с клавиатуры даты, то узел - свежий, удалять не надо. Если меньше, то узел устарел, нужно удалять. Проблема возникает только в случае равенства и месяцев, в таком случае нужно проверить день узла. Если он больше или равен дня введённой с клавиатуры даты, то узел - свежий, удалять не надо. Если меньше, то узел устарел. Программно эта проверка вообще выглядит смешно:
|
| Автор: Creder 26.5.2015, 09:28 | ||
Эх, во вемя удаления узлов вылетает.
|
| Автор: feodorv 26.5.2015, 12:40 | ||||
Обязано вылетать.
Зачем Вам temp, если он в точности равен node? Уберите temp, убедитесь, что код в if и else в точности совпадают. Итого:
|
| Автор: Creder 26.5.2015, 15:02 |
| Сработало! Спасибо вам! |
| Автор: Creder 27.5.2015, 23:22 | ||||
Хм. В общем, просмотрели мой код и ппоросили сделать в нем некоторые поправки. У меня к этому есть несколько вопросов.
|
| Автор: Creder 29.5.2015, 08:21 |
| .... |
| Автор: feodorv 29.5.2015, 08:48 | ||||||||||||
| Формально "препод" прав. Не http://habrahabr.ru/post/124417/ (в принудительном порядке), а принято добавлять, чтобы по имени сразу можно было понять, что переменная является членом класса. "m_" - для нестатических членов класса.
И для класса Tree тоже. И тогда уж все имена полей класса, не только каких-то избранных. Тогда и в конструкторе можно будет вернуться к day, month, year, name заместо урезанных d, m, y, n. Гм. Почему бы этот вопрос не задать интернету? Это одно из основополагающих понятий ООП; ведь могут потом и спросить, что это такое. Грубо говоря, никто не должен иметь прямой доступ к данным (полям) класса, а считывание и установка их значений должна происходить через так называемые функции геттеры (от английского get) и сеттеры (от английского set):
Да))) Везде в коде, где речь идёт об указателях. Но вот что волшебным образом должно поменяться, если Вы добавите этот класс в свой код?
Зачем всё это? Если их не объявлять, то компилятор их автоматически создаст, что в Вашем случае не хорошо:
Автоматически создаваемые конструктор копирования и оператор присваивания очень просты:
Послушайте, не в моих силах расписать здесь весь учебник C++. Вы всегда можете воспользоваться поиском, например, http://yandex.ru/yandsearch?text=%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D0%BE%D1%80%20%D0%BA%D0%BE%D0%BF%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%D0%BF%D0%BE%20%D1%83%D0%BC%D0%BE%D0%BB%D1%87%D0%B0%D0%BD%D0%B8%D1%8E%20c%2B%2B&clid=48648. Тема начинает далеко выходить за пределы удаления узлов из бинарного дерева и касаться основ C++. В main() бардак. Нужно как минимум вынести код ввода данных с клавиатуры в отдельные функции. |