Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.08.2012, 04:56   #1
Madmaxisss
Форумчанин
 
Регистрация: 12.07.2011
Сообщений: 158
По умолчанию удаляем последний элемент дерева

есть дерево одинарное pp

Код:
tree =^tt;
    tt =record
            val: string;
            link: tree;


var pp: tree; {в процессе программы оно составлено написано}

{мне нужно удалить элемент дерева}
procedure delete(dd: tree); {dd элемент древа}
var d1, d2: tree;
begin

     d1:=dd;
     d2:=dd^.link;
     while d2<>nil do 
     begin
          d1^.val:=d2^.val;
          d1:=d1^.link;
          d2:=d2^.link;
     end; 
     dispose(d1); {удаляем последний элемент дерева}
     d1:=nil; {после удаления когда выполняется print на последнем элементе появляются каля баля, почему???}
end;


PROCEDURE print;{выводим на экран}
begin
     while pp<>nil do
     begin
          writeln(pp^.val);
          pp :=pp^.link;
     end;
end;
Madmaxisss вне форума Ответить с цитированием
Старый 07.08.2012, 07:43   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
d1^.val:=d2^.val;
d1:=d1^.link;
d2:=d2^.link;
А зачем ты в процессе удаления перебираешь все элементы, пересаживая их вперед?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 07.08.2012, 08:21   #3
Madmaxisss
Форумчанин
 
Регистрация: 12.07.2011
Сообщений: 158
По умолчанию

Цитата:
А зачем ты в процессе удаления перебираешь все элементы, пересаживая их вперед?
дк не получится же удалить скажем средний элемент или получится??? хочешь сказать если к средниму элементу сделать dispose и присвоить nil он удалиться??? и на этом месте не будет ни каких "коля боля" при выполнение процедуры печати??

Цитата:
А зачем ты в процессе удаления перебираешь все элементы, пересаживая их вперед?
получается такое же удаление как в одномерном массиве.

Если можно попроще пожалуйста напишите

Последний раз редактировалось Stilet; 07.08.2012 в 18:07.
Madmaxisss вне форума Ответить с цитированием
Старый 07.08.2012, 09:34   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
получается такое же удаление как в одномерном массиве.
а должно быть такое же, как в связном списке!

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

Все элементы ПЕРЕСТАВЛЯТЬ НЕ НУЖНО!

посмотрите примеры, написанные уважаемым eoln тут и тут

или пример (с) Вадим Мошев можно взять тут

Последний раз редактировалось Serge_Bliznykov; 07.08.2012 в 09:54.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 07.08.2012, 11:14   #5
Madmaxisss
Форумчанин
 
Регистрация: 12.07.2011
Сообщений: 158
По умолчанию

Код:
procedure delete(dd: tree);
var d1, d2, d3: tree;
begin
     while dd<>nil do
     begin
          if dd=pp then
              pp:=pp^.link {начало будет сдвинуто}
          else
              d1^.link:=dd^.link; {здесь ОШИБКА!!!}
              d3:=dd;
              dd:=dd^.link;
              dispose(d3);
              continue;
     end;

end;

несастыковочка ошибка
Madmaxisss вне форума Ответить с цитированием
Старый 07.08.2012, 11:31   #6
Madmaxisss
Форумчанин
 
Регистрация: 12.07.2011
Сообщений: 158
По умолчанию

Код:
begin
     while dd<>nil do
     begin
          if dd=pasm then
              pasm:=pasm^.link
          else
              d1^.link:=dd^.link; {и даже так ошибка}
          d3:=dd;
          dd:=dd^.link;
          dispose(d3);
          continue;

     d1:=dd;
     dd:=dd^.link;
     end;
end;
Madmaxisss вне форума Ответить с цитированием
Старый 07.08.2012, 14:27   #7
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Если знаем адрес удаления, но не известен предыдущий элемент, то придётся пройтись циклом по дереву. А добавив двусвязность, можно вообще от цикла избавиться.
Если var pp: tree; - это единственная глобальная переменная, то процедура print после первого использования изменит её и мы "потеряем" дерево для следующих операций, поэтому надо где-то хранить корень дерева.
Ниже пример (глобальной можно оставить только first, мне просто расписывать лень)
Код:
type
tree =^tt;
    tt =record
            val: string;
            link: tree;
end;

var pp: tree; {в процессе программы оно составлено написано}
    i: char; first, tmp_del:tree;

{мне нужно удалить элемент дерева}
//можно оптимизировать, вынеся условия из цикла
procedure delete(dd: tree); {dd элемент древа}
var d1: tree;
begin
     pp:=first; //искать будем с начала
     d1 := pp;    
     while pp<>nil do begin

       if pp=dd then begin  //если нашли     
         if pp=first then first := first^.link else//если первый
           if pp^.link=nil then d1^.link := nil else//если последний
             d1^.link := pp^.link;//если в середине
         dispose(dd);//удаляем
         break;//и уходим
       end;

       d1 := pp;//запоминаем предыдущий элемент
       pp:=pp^.link;
     end
end;


PROCEDURE print;{выводим на экран}
begin
     pp:=first;//начинаем с самого начала
     while pp<>nil do
     begin
          writeln(pp^.val);
          pp :=pp^.link;
     end;
end;

BEGIN
  //заполним дерево
  new(pp);
  pp^.link:=nil;
  pp^.val:='a';
  first:=pp;
  for i :='b' to 'h' do begin
    pp^.link := new(tree);
    pp := pp^.link;
    pp^.val := i;
    if i='c' then tmp_del := pp;//просто какой-то элемент по адресу tmp_del будет удалён
    pp^.link := nil;
  end;

  print;
  delete(tmp_del);
  print
END.
eoln вне форума Ответить с цитированием
Старый 07.08.2012, 15:16   #8
Madmaxisss
Форумчанин
 
Регистрация: 12.07.2011
Сообщений: 158
По умолчанию

Цитата:
мне просто расписывать лень
вот уж расписал так расписал Большое спасибо eoln. Всё, разобрался.
Madmaxisss вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Найти последний элемент массива, величина которого находится в заданном диапазоне max_scotch Помощь студентам 0 16.05.2012 09:12
Удаляем комментарии с++. Почти... Arrioh Помощь студентам 6 19.04.2012 17:12
Последний элемент на первое место Abuhamed JavaScript, Ajax 1 06.03.2012 11:50
Одномерный массив. Необходимо заменить последний положительный элемент на второй элемент массива кумитэ Паскаль, Turbo Pascal, PascalABC.NET 1 19.12.2011 16:44
последний элемент очереди zhenya.ya Помощь студентам 0 31.03.2010 21:20