Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Произвольное дерево / 10 сообщений из 10, страница 1 из 1
07.09.2007, 14:46
    #34784595
ArtiS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
Имеется дерево

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
  TFreeTreeNode = ^TFreeTreeBranch; 
  TFreeTreeBranch = record
                      ID: integer  
                      PParent: TFreeTreeNode; //Указатель на родителя
                      PLeftChild: TFreeTreeNode; // Указатель на первого прямого потомка
                      PRightSibling: TFreeTreeNode; // Указатель на правого ровесника

  end;

Кто подскажет, как организовать в таком дереве поиск (получить указатель узел, имея ID узла)?
...
Рейтинг: 0 / 0
07.09.2007, 17:27
    #34785287
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
ArtiS wrote:

> Кто подскажет, как организовать в таком дереве поиск
Рекурсивно.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
07.09.2007, 17:28
    #34785297
ArtiS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
Да, но дерево большое, рекурсию будет использовать не рационально... Как бы ее развернуть?
...
Рейтинг: 0 / 0
07.09.2007, 17:34
    #34785309
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
ArtiS wrote:

> Да, но дерево большое, рекурсию будет использовать не рационально... Как
> бы ее развернуть?
Не рационально в плане чего? Скорости или памяти?
1) Память: Возьмите класс типа "stack" "fifo" и т.д. и впихивайте в него
указатели, обрабатывайте их по одному, обработанные удаляйте из списка.
2) Скорость: Создайте параллельно массив из записей, где будут храниться
инфа об id и указатель на id. Отсортируйте массив (quicksort'ом или другим
алгоритмом, более быстрым, чем стандартный (hash sort и т.д.)). Потом ищите
нужный id по нему двоичным поиском.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
07.09.2007, 20:00
    #34785592
teras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
ArtiSКто подскажет, как организовать в таком дереве поиск (получить указатель узел, имея ID узла)? Нужно еще определить отношения между узлами. Но вообще в таком дереве (из-за наличия PParent) все традиционные алгоритмы на дереве (поиск, обходы, вставка, удаление, если нужно - балансировка) итеративны.

Предполагая порядок такой, что ребенок содержит меньшие значения, правый сосед - большие, поиск выглядит примерно так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
function find(p:TFreeTreeNode; id: integer): TFreeTreeNode;
begin
	while (p <> nil) and (id <> p^.id) do begin
		if id < p^.id then
			p := p^.left;
		else
			p := p^.sibling;
	end;
	find := p;
end;
...
Рейтинг: 0 / 0
19.09.2007, 14:55
    #34811517
Melani
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
to teras
данное предложение будет работать верно если id создаётся в нужном порядке, тогда можно и сравнить id < p^.id . а если нет?
id - это номер. не думаю, что при вставке нового узла всё дерево будет перенумеровано в правильном порядке.
...
Рейтинг: 0 / 0
20.09.2007, 13:17
    #34814213
гавно
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
ArtiSДа, но дерево большое, рекурсию будет использовать не рационально... Как бы ее развернуть?

Разворачивайте, ради Аллаха. Но тогда придется стек самостоятельно обслуживать. Если хранить стек в виде односвязного списка на куче, то проблем с глубиной дерева не будет.
...
Рейтинг: 0 / 0
23.09.2007, 21:14
    #34820263
teras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
Melanito teras
данное предложение будет работать верно если id создаётся в нужном порядке, тогда можно и сравнить id < p^.id . а если нет?
id - это номер. не думаю, что при вставке нового узла всё дерево будет перенумеровано в правильном порядке. Не совсем так - просто при модификации дерева (это общее свойство всех деревьев поиска) нужно обеспечивать выполнение того-же самого инварианта. Например, делая вставку нового элемента в дерево - находить место для вставки в зависимости от такого-же сравнения. Это и будет соблюдением инварианта - а без него дерево поиска вообще построить не удастся.
Здесь я предположил один инвариант и написал для него процедуру поиска. Конечно, это самый простой, но, возможно, не самый любопытный инвариант - потому, что реально, в результате получается обычное бинарное дерево. Но, чтобы написать что-то более осмысленное, нужно иметь представление о предметной области. А именно - что нужно хранить, какие требуются алгоритмы, и ограничения.

Чтобы показать, что рекурсия здесь не нужна - можно набросать обход дерева в глубину (написано быстро и на глаз - так, что может содержать ошибки и неоптимальности, но суть все равно - верна) Цикл печатает дерево в инфиксном порядке (a+b). Другие порядки (префиксный +ab, постфиксный ab+) легко делаются из этого путем перестановки print()

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
while(p != NULL) {
	while(p->left)
		p = p->left;

	print(p->id);
	while( 1 ) {
		p = p->parent;
		if (p == NULL)
			break;

		print(p->id);
		if (p->sibling != NULL) {
			p = p->sibling;
			break;
		}
	}
}
Процедуры модификации работают используя указатель parent подобным образом.
...
Рейтинг: 0 / 0
23.09.2007, 22:45
    #34820313
Произвольное дерево
teras
p = p->parent;


Гы гы, насмешил! Так не честно - дерево само себе стек, вот тебе стек и не нужен.

В реале так редко бывает, что тебе позволительно строить такие деревья. Например, если дерево иммутабельно, и одна и та же ветка может принадлежать нескольким разным родительским узлам - разным версиям дерева. Вот это уже очень частый случай. Хрен тут что сделаешь без рекурсии или явного стека.
...
Рейтинг: 0 / 0
23.09.2007, 23:36
    #34820331
teras
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Произвольное дерево
ИндейЕврейский teras
p = p->parent;


Гы гы, насмешил! Так не честно - дерево само себе стек, вот тебе стек и не нужен.

В реале так редко бывает, что тебе позволительно строить такие деревья. Например, если дерево иммутабельно, и одна и та же ветка может принадлежать нескольким разным родительским узлам - разным версиям дерева. Вот это уже очень частый случай. Хрен тут что сделаешь без рекурсии или явного стека. Ну, если подходить с такой позиции, то и список, и массив, и переменная - это стек. А насчет реала не буду спорить - посмотри заглавный пост, что просили, то и написал. В таких условиях можно сделать итеративную реализацию для всех (по меньшей мере - большинства) типичных алгоритмов.
Кстати, запросы к структурам - они разные бывают. Всегда можно отслеживать владельца, вопрос только - что накладнее. И все. Например, у меня есть ощущение, что и в твоей структуре можно это делать. Причем разными способами (с точки зрения потребления памяти, монопольного доступа и т.д). А что узлы будут потреблять больше памяти - это не важно. Лишь бы исполнялось основное свойство итеративных алгоритмов - константное потребление памяти при исполнении.
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Произвольное дерево / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]