Добавление и удаление элементов в список - 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
: Добавление элементов в список. Эта функция запрашивает у пользователя ввод значений для добавления в список и добавляет их, если ввод корректен.