Добавление и удаление элементов в список - Turbo Pascal

Узнай цену своей работы

Формулировка задачи:

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

Решение задачи: «Добавление и удаление элементов в список»

textual
Листинг программы
program Project1;
 
type
  {Тип основных данных.}
  TData = Integer;
  {Указатель на элемент списка.}
  TPElem = ^TElem;
  //Элемент списка.
  TElem = record
    Data : TData; {Основные данные.}
    PNext : TPElem; {Указатель на следующий элемент.}
  end;
  //Список.
  TDList = record
    Cnt : Integer; {Количество элементов в списке.}
    PFirst, PLast : TPElem; {Указатели на первый и на последний элементы списка.}
  end;
 
{Процедура инициализации списка. Внимание! Эту процедуру можно выполнять
только в отношении пустого списка. Иначе, произойдёт утечка памяти.}
procedure Init(var aList : TDList);
begin
  aList.Cnt := 0;
  aList.PFirst := nil;
  aList.PLast := nil;
end;
 
{Добавление элемента в конец списка.}
procedure Add(var aList : TDList; const aData : TData);
var
  PElem : TPElem;
begin
  New(PElem);
  PElem^.Data := aData;
  PElem^.PNext := nil;
  if aList.PFirst = nil then
    aList.PFirst := PElem
  else
    aList.PLast^.PNext := PElem;
  aList.PLast := PElem;
  Inc(aList.Cnt);
end;
 
{Освобождение памяти, занятой под список.}
procedure ListFree(var aList : TDList);
var
  PElem, PDel : TPElem;
begin
  PElem := aList.PFirst;
  while PElem <> nil do begin
    PDel := PElem;
    PElem := PElem^.PNext;
    Dispose(PDel);
  end;
  Init(aList);
end;
 
{Распечатка всего списка.}
procedure LWriteln(var aList : TDList);
var
  PElem : TPElem;
  i : Integer;
begin
  PElem := aList.PFirst;
  i := 0;
  while PElem <> nil do begin
    Inc(i);
    if i > 1 then Write(', ');
    Write(PElem^.Data);
    PElem := PElem^.PNext;
  end;
  if i = 0 then
    Writeln('Список пуст.')
  else
    Writeln;
end;
 
{Удаление элемента из однонаправленного списка по указателю на предыдущий элемент.
Если указатель на предыдущий элемент равен NIL, то удаляется первый элемент списка.}
procedure Del(var aList : TDList; var aPPrev : TPElem);
var
  PDel : TPElem;
begin
  if aList.PFirst = nil then Exit;
 
  if aPPrev = nil then begin
    PDel := aList.PFirst;
    aList.PFirst := PDel^.PNext;
  end else begin
    PDel := aPPrev^.PNext;
    if PDel <> nil then
      aPPrev^.PNext := PDel^.PNext;
  end;
  if aList.PLast = PDel then
    aList.PLast := aPPrev;
  if PDel <> nil then begin
    Dispose(PDel);
    Dec(aList.Cnt);
  end;
end;
 
{Удаление из списка элементов с заданным значением.}
function DelByVal(var aList : TDList; const aData : TData) : Integer;
var
  PElem, PPrev : TPElem;
  Cnt : Integer;
begin
  Cnt := 0;
  PPrev := nil; {Указатель на предыдущий элемент.}
  PElem := aList.PFirst; {Указатель на текущий элемент.}
  while PElem <> nil do begin
    if PElem^.Data = aData then begin
      {Переход к следующему элементу надо выполнить перед вызовом Del(),
      потому что процедура Del() удалит текущий элемент.}
      PElem := PElem^.PNext;
      Del(aList, PPrev);
      Inc(Cnt);
    end else begin
      PPrev := PElem;
      PElem := PElem^.PNext;
    end;
  end;
  DelByVal := Cnt; {Количество удалённых элементов.}
end;
 
{Добавление элементов в список.}
procedure WorkAdd(var aList : TDList);
var
  S : String;
  Data : TData;
  Code : Integer;
begin
  Writeln('Добавление элементов в список.');
  Writeln('Ввод каждого значения завершайте нажатием Enter.');
  Writeln('Чтобы прекратить ввод, оставьте пустую строку и нажмите Enter.');
  repeat
    Write('Элемент №', aList.Cnt + 1, ': ');
    Readln(S);
    if S <> '' then begin
      Val(S, Data, Code);
      if Code = 0 then
        Add(aList, Data)
      else
        Writeln('Неверный ввод. Повторите.');
    end;
  until S = '';
  Writeln('Ввод элементов списка завершён.');
end;
 
var
  L : TDList;
  Data : TData;
  Cmd, Code, Cnt : Integer;
  S : String;
begin
  {Начальная инициализация списка.}
  Init(L);
 
  repeat
    {Меню.}
    Writeln('Выберите действие:');
    Writeln('1: Добавление элементов в список.');
    Writeln('2: Распечатка всего списка.');
    Writeln('3: Проверка списка на пустоту.');
    Writeln('4: Удаление элементов по условию.');
    Writeln('5: Очистка списка.');
    Writeln('6: Выход.');
    Write('Введите команду: ');
    Readln(Cmd);
    case Cmd of
      1: WorkAdd(L);
      2:
      begin
        Writeln('Содержимое списка:');
        LWriteln(L);
      end;
      3:
        if L.PFirst = nil then
          Writeln('Список пуст.')
        else
          Writeln('Список непустой.');
      4:
      begin
        Writeln('Элементы с заданным значением будут удалены из списка.');
        Writeln('Чтобы отменить операцию оставьте пустую строку и нажмите Enter.');
        repeat
          Write('Значение: ');
          Readln(S);
          if S <> '' then begin
            Val(S, Data, Code);
            if Code = 0 then begin
              Cnt := DelByVal(L, Data);
              Writeln('Количество удалённых элементов: ', Cnt);
            end else
              Writeln('Неверный ввод. Повторите.');
          end;
        until S = '';
      end;
      5, 6:
      begin
        ListFree(L);
        Writeln('Список удалён из памяти (очищен).');
      end;
      else
        Writeln('Незарегистрированная команда. Повторите ввод.');
    end;
  until Cmd = 6;
 
  Writeln('Работа программы завершена. Для выхода нажмите Enter.');
  Readln;
end.

Объяснение кода листинга программы

Этот код написан на Turbo Pascal и представляет собой программу для работы со списком. Он содержит следующие функции и процедуры:

  • Init: Инициализация списка. Эта процедура может быть выполнена только для пустого списка, иначе происходит утечка памяти.
  • Add: Добавление элемента в конец списка. Эта функция создает новый элемент, устанавливает его данные и связывает его с следующим элементом в списке.
  • ListFree: Освобождение памяти, занятой под список. Эта процедура проходит по списку, освобождая память для каждого элемента, начиная с первого.
  • LWriteln: Распечатка всего списка. Эта функция проходит по списку, печатая каждый элемент, и затем выводит строку Список пуст.
  • Del: Удаление элемента из списка по указателю на предыдущий элемент. Если указатель на предыдущий элемент равен nil, то удаляется первый элемент списка.
  • DelByVal: Удаление элементов с заданным значением. Эта функция принимает список, значение, которое нужно удалить, и возвращает количество удаленных элементов.
  • WorkAdd: Добавление элементов в список. Эта функция запрашивает у пользователя ввод значений для добавления в список и добавляет их, если ввод корректен.
  • Readln: Чтение строки с консоли. Эта функция читает строку с консоли и возвращает ее.
  • Write: Вывод строки на консоль. Эта функция выводит строку на консоль.
  • Writeln: Вывод строки с консоли. Эта функция выводит строку на консоль.
  • ListFree: Освобождение памяти, занятой под список. Эта процедура проходит по списку, освобождая память для каждого элемента, начиная с первого.
  • Del: Удаление элемента из списка по указателю на предыдущий элемент. Если указатель на предыдущий элемент равен nil, то удаляется первый элемент списка.
  • DelByVal: Удаление элементов с заданным значением. Эта функция принимает список, значение, которое нужно удалить, и возвращает количество удаленных элементов.
  • WorkAdd: Добавление элементов в список. Эта функция запрашивает у пользователя ввод значений для добавления в список и добавляет их, если ввод корректен.

Оцени полезность:

9   голосов , оценка 4.222 из 5
Похожие ответы