Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Центр помощи > [Delphi] TreeView |
Автор: Неопытный 12.1.2007, 09:45 |
Вопрос по TreeView. Имеется список Например: 1. 1.1 1.2. 2. 2.1. 2.2 2.3. 2.3.1 3. ... Как Забить дерево. А то алгоритмы лезут какие-то нерациональные. Типа берем элемент списка, Пока точки не кончились берем до первой точки. Переходим в этот узел. конец Пока. Добавляем ветку Так как узел еще может не существовать (список перемешан) то нужно его еще найти (двойной перебор), а может предварительно отсортировать список - тупо. Может есть какие соображения? |
Автор: Beltar 12.1.2007, 10:20 | ||
Тебе надо заполнить дерево определенной структурой и его собственные механизмы не подходят, т. к. не сохраняют данные? В одном своем проекте я сделал сохранение и загрузку подсоединенных к узлам данных используя только сведения о числе имеющихся у узла дочерных. Для этого использовал стек. Делал такую структуру
Натурально массив из них. Брал узел, добавлял его к последнему в массиве. Уменьшал у того к которому добавил Nested. Заносил новый узел в стек и проверял его Nested на =0, если равно, уменьшал указатель вершины и проверял следующий, так пока не находил к кому прибавлять. Если прибавлять не к кому (стек пуст) прибавлял к узлу по умолчанию. Правда я не уверен, что у тебя похожий случай. Можно на реальные данные для заполнения взглянуть? |
Автор: Неопытный 12.1.2007, 10:23 | ||
В смысле реальные. Я же привел пример списка. |
Автор: Beltar 12.1.2007, 15:10 |
Значит студент с контрольной. ![]() Загрузи строки в TStringList и сделай ему Sorted:=true; После этого по моему можно сделать массив из структур типа той, что я указал выше - TTreeNode и целое. Индекс элемента массива будет уровень на который надо добавлять. А целое число - номер. В начале весь массив забить нулями и нилами. Парсишь строку. Выделяешь 1-е число и сравниваешь с первым число в массиве, если совпадают идешь дальше пока не найдешь различие. Добавляешь узел как Child узлу который указан в соотв. ячейке и записываешь в следующую ячейку ссылку на только что добавленный. Т. е. начал ты работать. у тебя в ячейке 1 лежит 0 записан узел nil. Ты считал 1. Сразу есть различие, ты добавляешь узел к nil (т. е. в корень) в ячейку 2 пишешь ссылку новый узел и 0, а в ячейку 1 в поле Integer 1. Далее считал 1 и еще раз 1. Т. е. узел2-го уровня. Из ячейки 2 получаешь узел куда надо новый добавлять. По моему должно работать и никакого поиска по дереву, все кэширно. ![]() Добавлено @ 15:12 С точками в конце думаю надо решить, они есть или нет. Думаю если есть парсить проще. Просто после выделения числа проверяешь номер текущего символа на последность. |
Автор: Неопытный 15.1.2007, 18:27 | ||
Все равно перебор. Элгоритм работает для списка из 500 эл довольно долго. Может быть все-таки кто подскажет алгоритм более рациональный! |
Автор: aktuba 15.1.2007, 18:45 |
А другого варианта нет. Точнее есть, но это только модификации этого варианта. Ты лучше покажи, какой у тебя код вышел - люди помогут оптимизировать... |
Автор: Beltar 15.1.2007, 22:20 |
Я загружал в TreeView в своей проге за секунды десятки тысяч элементов (Sempron 2500). Ты скорее всего не делаешь TreeView.Items.BeginUpdate и после загрузки EndUpdate, и он у тебя перерисовывается. Также Items имеет смысл запомнить в отдельной переменной это избавит от необходимости искать его у дерева при каждом обращении. Возможно ты, также, StringList заполняешь со вкл. Sorted, тогда он после каждого добавления сортируется. Кстати, я что-то не помню, можно ли у StringList'а задать емкость. Никакого поиска по дереву в моем алгоритме нет. Найдя в какой уровень надо добавить узел ты сразу получаешь узел к которому надо добавлять из массива. Кстати, моя программулина реализовывала еще добавление списка узлов с учетом структуры. Она работает с файлами и часто отражает структуру их размещения по папкам. Никаких тормозов не замечалось и в этом случае. Работает по похожему принципу, что я тебе описал. |