Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > задача на динамическую память


Автор: Fardon 6.12.2009, 23:51
Всем добрый день.  
Препод по программированию задал задачку. Что-то никак не соображу, как решается.  
Задача по Динамическим структурам данных, по паскалю в частности. Хотя жёстко к языку не привязана. Так что интересует алгоритм решения а не реализация . Вообще задача вроде как стандартная и видел много вопросов по ней. Но вот  решения, которое подходит мне не нашёл. 
Есть однонаправленный список, который может быть зациклен  
Задание такое – определить зацикленный ли список? 
Данные и условия: 
user posted image 
Список может быть зациклен не только на предыдущий элемент.  Т.е решение запустить 2 прохода по списку с разным шагом в 2 не подходит. 
Перезаписывать, добавлять что-либо в самом списке нельзя. Т.е добавить флаг-" здесь мы были" нельзя. 
Создавать переменные, которые зависят от количества элементов в цикле нельзя. Т.е создать ещё список с пройденными адресами нельзя. 
Количество элементов списка (N) неизвестно. И максимальное количество проходов по списку, за которое точно можно будет сказать, что список не зациклен (или зациклен), не должно превышать N. Т.е тупой поиск в пройденных элементах использовать нельзя.  
Вродь всё)   
Я уже и не знаю что делать. Мож что-нить связанное с указателями и памятью тут? Помогите пожалуйста)

Автор: Pitlord 7.12.2009, 01:17
А перед циклом сохранить указатель на текущий элемент списка нельзя?

Добавлено через 1 минуту и 5 секунд
Имею ввиду это:
Код

pointer = plist;
plist := plist^.next;

while ((plist <> nil) and (plist <> pointer)) do
begin
    plist := plist^.next;
end;

Автор: maxim1000 7.12.2009, 09:17
делаем два итератора по списку
в цикле один сдвигаем на один элемент, второй - на два
работаем, пока не дойдём до конца или не обнаружим, что оба итератора указывают на один и тот же элемент

расстояние между ними на каждом шаге увеличивается на 1, так что, когда номер шага кратен периоду, итераторы будут указывать на один и тот же элемент (если список зациклен)

начальная нециклическая часть может привести к тому, что первый период будет пропущен, но рано или поздно оба итератора войдут в циклическую часть, а после этого сравняются на первом же шаге с номером кратным периоду

Автор: Fardon 7.12.2009, 17:35
Цитата(maxim1000 @ 7.12.2009,  09:17)
делаем два итератора по списку
в цикле один сдвигаем на один элемент, второй - на два
работаем, пока не дойдём до конца или не обнаружим, что оба итератора указывают на один и тот же элемент

расстояние между ними на каждом шаге увеличивается на 1, так что, когда номер шага кратен периоду, итераторы будут указывать на один и тот же элемент (если список зациклен)

начальная нециклическая часть может привести к тому, что первый период будет пропущен, но рано или поздно оба итератора войдут в циклическую часть, а после этого сравняются на первом же шаге с номером кратным периоду

Спасибо! smile Как раз то, что нужно. 
немного не додумал) теперь кажется так легко smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)