1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Бинарные деревья(функция Dispose), Проблема с удалением листьев дерева
Здравствуйте. Помогите, пожалуйста, решить проблему: при удалении листьев дерева и его повторном обходе Turbo Pascal вылетает(закрывается). Пожскажите в чем ошибся, описание алгоритмов формирования, вывода и остальное, кроме процедуры удаления листьев брал с FAQа сайта. Вот описание процедур(создания, печати и удаления "листвы"):
procedure add(var t:ttree;x:ttype); procedure createnode(var p:ttree;n:ttype); begin new(p); p^.key:=n; p^.left:=nil; p^.right:=nil; end; begin if t=nil then createnode(t,x) else with t^ do begin if key<x then add(right,x) else if key>x then add(left,x);end; end;
procedure PrintDown(T: TTree); begin if T=nil then exit; with T^ do begin write(key,' '); writeln; PrintDown(left); PrintDown(right); end end;
{процедура удаления листьев} procedure del1(var v:ttree); var t:ttree; inf: integer; begin if v=nil then exit; del1(v^.left); del1(v^.right); if (v^.left=nil) and (v^.right=nil) then dispose(v); end;
В процедуре удаления листа... Во-первых, после Dispose значение указателя не является нулевым, а является неопределенным, то есть, куда такой указатель тебя зашлет при вызове PrintDown - одному процессору известно... А во-вторых, запускать рекурсию нужно только тогда, когда не выполняется условие (left = nil) and (right = nil), а не ВСЕГДА... Вот так должно работать:
procedure del1(var v:ttree); var t: ttree; begin if v = nil then exit;
if (v^.left=nil) and (v^.right=nil) then begin dispose(v); v := nil; end else begin del1(v^.left); del1(v^.right); end; end;