скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Динамический список 3



unit dlist3_;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Button1: TButton;
    Button2: TButton;
    Label3: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

type
  TPStudent = ^TStudent; //указатель на тип TStudent

  TStudent = record
    f_name: string[20]; // фамилия
    l_name: string[20]; // имя
    next: TPStudent; // следующий элемент списка
  end;

var
  head: TPStudent; // начало (голова) списка

procedure TForm1.Button1Click(Sender: TObject);
var
  node: TPStudent; // новый узел списка
  curr: TPStudent; // текущий узел списка
  pre: TPStudent; // предыдущий, относительно curr, узел
begin
  new(node); // создание нового элемента списка
  node^.f_name := Edit1.Text;
  node^.l_name := Edit2.Text;
   // добавление узла в список
   // сначала найдем подходящее место в списке для узла
  curr := head;
  pre := nil;
   { Внимание!
     если приведенное ниже условие заменить
     на (node.f_name>curr^.f_name)and(curr<>NIL)
     то при добавлении первого узла возникает ошибка времени
     выполнения, так как curr = NIL и, следовательно,
     переменной curr.^name нет!
     В используемом варианте условия ошибка не возникает, так как
     сначала проверяется условие (curr <> NIL), значение которого
     FALSE и второе условие в этом случае не проверяется.
   }
  while (curr <> nil) and (node.f_name > curr^.f_name) do
  begin
     // введенное значение больше текущего
    pre := curr;
    curr := curr^.next; // к следующему узлу
  end;
  if pre = nil
    then
  begin
          // новый узел в начало списка
    node^.next := head;
    head := node;
  end
  else
  begin
          // новый узел после pre, перед curr
    node^.next := pre^.next;
    pre^.next := node;
  end;

  Edit1.text := '';
  Edit2.text := '';
  Edit1.SetFocus;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  curr: TPStudent; // текущий элемент списка
  n: integer; // длина (кол-во элементов) списка
  st: string; // строковое представление списка
begin
  n := 0;
  st := '';
  curr := head;
  while curr <> nil do
  begin
    n := n + 1;
    st := st + curr^.f_name + ' ' + curr^.l_name + #13;
    curr := curr^.next;
  end;
  if n <> 0
    then ShowMessage('Список:' + #13 + st)
  else ShowMessage('В списке нет элементов.');
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  head := nil;
end;

// щелчок на кнопке Удалить

procedure TForm1.Button3Click(Sender: TObject);
var
  curr: TPStudent; // текущий, проверяемый узел
  pre: TPStudent; // предыдущий узел
  found: boolean; // TRUE - узел, который надо удалить, есть в списке

begin
  if head = nil then
  begin
    MessageDlg('Список пустой!', mtError, [mbOk], 0);
    Exit;
  end;
  curr := head; // текущий узел - первый узел
  pre := nil; // предыдущего узла нет
  found := FALSE;

  // найти узел, который надо удалить
  while (curr <> nil) and (not found) do
  begin
    if (curr^.f_name = Edit1.Text) and (curr^.l_name = Edit2.Text)
      then found := TRUE // нужный узел найден
    else // к следующему узлу
    begin
      pre := curr;
      curr := curr^.next;
    end;
  end;
  if found then
  begin
            // нужный узел найден
    if MessageDlg('Узел будет удален из списка!',
      mtWarning, [mbOk, mbCancel], 0) <> mrYes
      then Exit;

            // удаляем узел
    if pre = nil
      then head := curr^.next // удаляем первый узел списка
    else pre^.next := curr.next;
    Dispose(curr);
    MessageDlg('Узел' + #13 +
      'Имя:' + Edit1.Text + #13 +
      'Фамилия:' + Edit2.Text + #13 +
      'удален из списка.',
      mtInformation, [mbOk], 0);
  end
  else // узла, который надо удалить, в списке нет
    MessageDlg('Узел' + #13 +
      'Имя:' + Edit1.Text + #13 +
      'Фамилия:' + Edit2.Text + #13 +
      'в списке не найден.',
      mtError, [mbOk], 0);
  Edit1.Text := '';
  Edit1.Text := '';
  Edit1.SetFocus;
end;


end.
Скачать весь проект





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook