![]() |
Модераторы: LSD, AntonSaburov |
![]() ![]() ![]() |
|
ci5 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 24.12.2008 Репутация: нет Всего: нет |
Здравствуйте! Стоит задача создать дерево, каждый узел которого содержит: id name hash child parrent. Реализовать нужно:вставка в нужное место, удаление ветки, её расщепление, остальные легко реализуемые.
Сортировка тут не нужна, по сути у нас только имя главное в дереве из значений. Собственно какие вижу проблемы: 1. не пойму как быть тут с id. В задании у нас возможно удалять как ветвь, так и отдельные элементы дерева. Тоесть если нужно сделать "расщепление", то надо прошлые ссылки детей присвоить к новому, более высокому родителю, который был родителем расщепленного. Но при этом при всём у нас id удалённого элемента будет недоступен. Как тут поступить ? Как идея, вести полный список id и при удалении одного, делать недоступными id и удалённого, и его детей, выдавая детям удалённого родителя новые id, которые выдаются исходя из общих id (sizeId). Может есть какое-то более разумное решение ? 2. Какую коллекцию лучше использовать ? Количество элементов заранее неизвестно. Сортировки по возрастанию и убыванию никакой. Сказали что вроде тут надо использовать LinkedList и использовать встроенный итератор для вставки в определённое место. Но я никак не могу себе представить себе такой подход. Это какая-то архитектура дерева в ширину будет, а не в ширину и глубину. То есть у нас по сути будет всего один элемент, у которого будет ссылка next на голову, хотя если смотреть на дерево, то таких элементов может быть довольно много. Вот многомерные массивы можно представить как дерево, только кол-во элементов определено, а вот тут никак не получается. Что касается самих полей:
Я вот как-то так это вижу. Подскажите куда копать. Заранее спасибо. |
|||
|
||||
dorogoyIV |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 26.3.2007 Репутация: 3 Всего: 46 |
создаешь класс со своими полями: id name hash child parrent
в этом классе реализуешь метод toString() - это будет отображаться в дереве. пишешь модель дерева на основе своего класса... потом уже с моделью дерева можно работать - вставлять, удалять, ... ![]() |
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Добавлено через 3 минуты и 41 секунду не HashMap, a Map - реализацию Map тоже можно менять по вкусу. |
|||
|
||||
dorogoyIV |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 26.3.2007 Репутация: 3 Всего: 46 |
|
|||
|
||||
ci5 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 24.12.2008 Репутация: нет Всего: нет |
Спасибо за комментарии. По ним:
dorogoyIV, спасибо конечно за код, но с awt и swing я еще дел не имел, поэтому эту задачу думаю выполнить в консольном приложении. math64, вы писали: >List<Node> roots; // Узлы у которых parent = null; я так понимаю это вершины наших деревьев будут. А не проще их просто зациклить на себя? к примеру создается head при создании объекта, это будет наша вершина и ссылаться просто на себя в parrent. И еще, с коллекциями еще не приходилось работать. В примитивных типах я так понимаю там используются обертки для работы с коллекциями. Там ничего для понимания сложного нету. А вот тут как получится ? Мне придется получается переопределять все методы LinkedList и описывать, или создавать класс в соответствии с интерфейсом List ? Извиняюсь, если вопрос глупый. Но как-то не могу понять этого момента. |
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Пользуйтесь стандартными классами списков - Вам их вполне достаточно. Но используйте везде List<Node>, кроме конструктора при необходимости new LinkedList<Node>() можно заменить на new ArrayList<Node>() и наоборот.
По поводу List<Node> roots. Вам нужно уметь удалять любой узел, в том числе и корневой. Тогда (если он удаляется без дочерних элементов), бывшие дочерние элементы станут несколько корневыми, поэтому не один Node root, а список. |
|||
|
||||
ci5 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 24.12.2008 Репутация: нет Всего: нет |
Спасибо. Уже можно сказать получил дерево, но есть некоторые непонятки.
Для интерфейса Map использую LinkedHashMap. Не пойму как получить ключ по значению. Значение по ключу понятно как получать, но возможно ли наоборот? В английском не силен, но вроде стандартных методов как я понял на это дело нету ? |
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Если Map заполнена правильно (ключом является Node.id), то чтобы получить ключ по node, нужно посмотреть на поле node.id.
Если заполнена неправильно - то только перебором всех ключей. Если у node меняется id, нужно сначала удалить его из map, используя старый id в качестве ключа, изменить id и добавить в map по новому id. Предполагается, что у всех Node уникальный id, отличный от других. |
|||
|
||||
ci5 |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 24.12.2008 Репутация: нет Всего: нет |
На счет Map. Тоесть в карте вообще можно не перебирать элементы, если коллекция правильно составлена ? (головной элемент сказали сделать неудаляемым)
И еще вопрос если можно, связанный с сериализацией. Не могу понять в чем ошибка.
Работает это всё хорошо, но только не десериализация (а может и сериализация тоже)
Ругается в getNode на > throw new TreeIndexOutOfBoundsException(); По сути, я же выводил дерево до сериализации. Тут её сделал и для проверки вызвал у сериализованного объекта метод getSize, который отработал как надо. Боюсь я где-то с map что-то не так делаю. (TreeIndexOutOfBoundsException - public class TreeIndexOutOfBoundsException extends RuntimeException) забыл сказать. это у меня 2 класса. в главном, где main aTree.addGroupNode(0); - просто сделал цикл на addNode, а ноль это id корня Это сообщение отредактировал(а) ci5 - 9.11.2011, 20:43 |
||||||
|
|||||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
В addNode я бы вернул созданный Node. В случае ошибки вернуть null или throw исключение.
В getNode перебор индексов не нужен - достаточно
С сериализацией я особо не разбирался, но, возможно, удобнее сериализировать в xml? Так как xml - текстовый файл, легко проверить, правильно ли прошла сериализация. Добавлено через 4 минуты и 50 секунд Кстати, при map сериализировать не надо - после десериализации нужно пробежаться по дереву заполнить map, при сериализации лучше избегать дублирования информации. |
|||
|
||||
ci5 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 24.12.2008 Репутация: нет Всего: нет |
Спасибо большое! Учту. Про сериализацию в xml... Вроде же сериализация сохраняет я так понимаю как бы массив байт. Если я его загоню в xml, то как я опять же получу в нём информацию, лёгкую для прочтения? Хотя думаю почитаю про xml и всё встанет на свои места.
Ошибку в коде нашел. сравнивал объекты через ==, вместо equals ![]() |
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
xml - текстовый файл вида:
Легко проверить правильно ли сохранилось. |
|||
|
||||
ci5 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 24.12.2008 Репутация: нет Всего: нет |
Прошу помочь еще в одном деле. Не первый час мучаюсь с удалением ветки вместе с её элементами и не могу довести до полностью рабочего состояния.
Боюсь тут много излишков кода. К примеру я получаю дерево такое, как на рисунке (внутри узла его id) ![]() после чего удаляю второй по номеру id элемент. Он должен удалить мне все, кроме 0, 1, 3. Но он удаляет мне все, кроме 0,1,3, 8. При этом nodesById.size выдаёт мне что наша карта содержит 9 элементов. Я понимаю откуда эти 9 элементов взялись. Просто детей от id=5 мы не удаляли, а только затерли его родителя. В общем в карте map у нас содержатся элементы 0,1,3,8 реальных, а остальные 5 с Node=null, поэтому они и не выводятся. Что тут делать ? чистить постоянно коллекцию на нулевые ноды или как ? и так уже запутался с вроде бы как не сложным делом. Да и элемент с id=8 тоже не понятно почему вылазит. Разве что только iter.next сразу прыгает на второй элемент. |
|||
|
||||
math64 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
Не нужны лишние проверки.
В то же время других не хватает. Нужно проверять результат nodesById.get(id) на null Для удаления элемента из списка не нужно перебирать элементы - вызывай просто remove(). Если узел удаляется с дочерними элементами, вызови рекурсивно удаление дочерних элементов. Примерно так:
|
|||
|
||||
ci5 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 36 Регистрация: 24.12.2008 Репутация: нет Всего: нет |
В целом тут всё понятно и прозрачно.
В коде на итераторе я ловлю исключение
Я так понимаю проблема в том, что изменяется коллекция, а так как итератор по ней бегает в данный момент, то и выбрасывается исключении о том, что коллекция изменилась. (в вашем коде подправил только delete(del); - 5 стр на deleteNode(del); ) Первое что на ум приходит это получать массив из ссылок, которые лежат в коллекции на объекты, но это опять же загромождать программу и понижать её скорость. Как поступить, подскажите пожалуйста. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Java" | |
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |