Файл: 6. Разработка контейнера на основе адресного списка.pdf

Добавлен: 20.10.2018

Просмотров: 1030

Скачиваний: 17

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

 

6. Разработка контейнера на основе адресного списка 

В разделе 4 в качестве примера описания и использования классов был 

представлен  контейнер  на  основе  массива.  Как  известно,  существует  и 

альтернативная  реализация  контейнера,  которая  использует  адресные  связи 

между  элементами  и  механизм  динамического  распределения  памяти. 

Сравнение  и  алгоритмическая  реализация  этих  вариантов  представлена  в 

классических  учебниках  по  Структурам  Данных.  Краткое  введение  в  этот 

материал можно найти в учебном пособии [ 8 ]. 

Динамический  адресный  список  представляет  из  себя  набор  элементов, 

занимающих  свои  отдельные  области  памяти.  Элементы  связываются  в 

логическую последовательность с помощью адресных полей.  

Можно  предложить  два  варианта  объектной  реализации  адресного 

списка.  Более  общий  вариант  предполагает  использование  для  связи 

собираемых в контейнер объектов вспомогательных объектов-посредников

Более  простой  вариант  основан  на  включении  служебных  адресных  полей 

непосредственно  в  сами  объекты,  поэтому  он  возможен  только  если 

доступно исходное описание класса хранимых объектов. 

Рассмотрим  первый  вариант,  причем  в  качестве  примера  возьмем 

объектную  реализацию  контейнера  для  хранения  и  обработки  графических 

объектов-окружностей.  В  дальнейшем,  после  изучения  принципа 

полиморфизма

этот 

простейший 

вариант 

контейнера 

будет 

модифицирован  и  получит  способность  хранить  любые  графические 

объекты. 

Схематично  списковый  контейнер  для  объектов-окружностей  можно 

представить следующим образом. 

 

 

 

 

 


background image

 

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 

 

Каждый  отдельный  элемент  списка  будем  рассматривать  как 

самостоятельный  объект,  отвечающий  за  хранение  адреса  следующего 

элемента  и  адреса  связанной  с  ним  окружности.  Сам  контейнер  как  набор 

элементов-объектов  тоже  является  объектом,  реализующим  основную 

функциональность динамического списка. 

Для  программной  реализации  прежде  всего  необходимо  ввести  два 

класса:  класс  «ЭлементСписка»  и  класс  «СписковыйКонтейнер». 

Неформально структуру этих классов можно описать следующим образом.  

Класс «ЭлементСписка» должен содержать: 

  адрес  следующего  элемента-объекта  (поле  данных  объектного 

типа) 

  адрес окружности (поле данных классового типа  Circle) 

  одно или несколько информационных полей (при необходимости) 

  конструктор(ы)  для  создания  нового  элемента-объекта  с 

необходимыми значениями свойств 

  методы доступа к закрытым адресным данным 

 

Класс «СписковыйКонтейнер» должен содержать: 

элемент 1 

  

адрес второго 

элемента 

адрес  

окружности 

 

 

адрес первого 

элемента

 

элемент 2 

  

адрес третьего 

элемента 

адрес  

окружности 

 

 

элемент 3 

  

адрес следующего 

элемента 

адрес  

окружности 

 

 

окружность 1

 

окружность 2

 

окружность 3

 


background image

 

 

  адрес первого элемента списка (поле объектного типа) 

  адрес последнего элемента списка (при необходимости) 

  одно или несколько информационных полей (при необходимости) 

  конструктор(ы)  для  создания  контейнера  в  начальном  состоянии 

(чаще всего пустом) 

  методы доступа к информационным полям (при необходимости) 

  методы добавления, удаления, поиска и итеративной обработки 

 

Формализованное описание класса «ЭлементСписка» : 

TPosrednik  =  class  

private  

   ItemInf : string;   //  или другой необходимый тип 

   Next : TPosrednik;   // свойство-указатель на следующий элемент 

   Circ : TCircle;  // свойство-указатель адресуемой окружности  

public   

   сonstructor  Create (aInf : string;  aNext : TPosrednik;   aCirc : TCircle );  

   function   GetNext : TPosrednik;    // получение адреса след. элемента 

   function  GetCirc : TCircle;    // важно: метод для доступа к окружности! 

   function   GetInf : string;  

   procedure   SetNext (aNext : TPosrednik);   // изменение адреса след. эл-та 

   procedure   SetCirc (aCirc : TCircle);  // для присоединения другой окр-ти 

   procedure   SetInf (aInf : string);  // для изменения информационного поля 

end; 

 

class   Posrednik  { 

   private   int   ItemInf;   //  или другой необходимый тип 

   private   Posrednik   Next;   // свойство-указатель на следующий элемент 

   private   Circle   Circ;  // свойство-указатель адресуемой окружности  

 


background image

 

 

   public  Posrednik (int  aInf,  Posrednik   aNext,  Circle  aCirc) {…;}  

   public  Posrednik   GetNext( ) {…;}    // получение адреса след. элемента 

   public  Circle   GetCirc( ) {…;}  // важно: метод для доступа к окр-ти! 

   public  int   GetInf ( ) {…;}  

   public  void  SetNext (Posrednik   aNext) {…;}  // изменить адрес след. эл-та 

   public void  SetCirc (Circle  aCirc) {…};  // для присоединения другой окр. 

   public  void   SetInf (int   aInf) {…};  // для изменения информац. поля 

};

 

 

Описание  основного  класса  «СписковыйКонтейнер»  (для  упрощения 

изложения добавление нового элемента будем производить в начало списка): 

CircleListContainer = class 

private 

   ContInf : string

   First : TPosrednik;  // указатель на первый элемент списка 

public   

   сonstructor   Create (ainf : string);  // создание пустого списка 

   function  GetFirst : TPosrednik;   

  //  здесь должны быть методы доступа к информационному свойству 

   procedure  Add (ainf : string;  aCirc : TCircle);  // добавление объекта 

   function  Delete (ainf : string) : boolean;  // удаление эл-та по его инф. части  

   function  Search (aRad : integer) : TPosrednik;  // поиск эл-та по радиусу окр. 

   procedure  ShowAll;   // итератор для отображения всех окружностей 

   procedure  MoveAll (dx, dy : integer);  // итератор-перемещатель 

 end; 

 

Программная реализация некоторых методов (обратить внимание на 

использование Get-методов для доступа к закрытым данным объектов-

элементов списка и объектов-окружностей!): 

constructor   CircleListContainer.Create (ainf : string);   


background image

 

 

    begin   First := nil;   ContInf := ainf;   

    end; 

procedure   CircleListContainer.Add ( ainf : string;  aCirc : TCircle);  

    begin   // напомним, что добавление — в начало списка! 

          First := TPosrednik.Create (ainf, First, aCirc);  //  красиво и компактно! 

    end;     

procedure  CircleListContainer.ShowAll;  

    var   Temp : TPosrednik;   // вспом. объектная перем. для прохода по списку 

    begin  

 

Temp := First;     

 

while (Temp <> nil)  do    

 

 

begin 

 

 

   Temp.GetCirc.Show;    // доступ к методу объекта-окружности 

 

 

   Temp := Temp.GetNext;   //  получение адреса след. элемента 

 

 

end; 

    end; 

function  CircleListContainer.Search (aRad : integer) : TPosrednik; 

   var   Temp : TPosrednik; 

   begin 

      result := nil

      Temp := First; 

      while (Temp <> nil)  do    

 

if  (Temp.GetCirc.GetR = aRad)   then 

 

begin 

 

   result := Temp; 

 

   break

 

end    

 

else  Temp := Temp.GetNext 

   end;