Шаблон иерархической структуры данных в памяти (односвязный список, содержащий статический массив указателей на объекты), страница 4

Функция загрузки данных из файла

int LoadFile(char * filename);

Входные данные: имя входного файла (filename)

Выходные данные: 0 – если данные загружены успешно, -1 – если произошла ошибка

Перед загрузкой данных, удаляются все элементы, содержащиеся в структуре данных.

Данные загружаются и текстового файла, работа с файлом организована с помощью потоков. Внутри файла каждый элемент списка записывается одной строкой. Таким образом, считывание производится построчно до конца файла. В начале каждой строки стоит целое количество, задающее количество элементов в элементе списка (массиве). После определения количества элементов, создается новый элемент списка, и все элементы поочередно переписываются из файла в массив. Если оказывается, что это значение больше допустимого (MAXN), то загрузка из файла прекращается, удаляются уже записанные элементы, и функция возвращает –1 (ошибка). 

Функция сохранения в файле

void SaveFile(char * filename);

Входные данные: имя входного файла (filename)

Выходные данные: нет

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

Функция балансировки

void Balancing();                                            

Входные данные: нет

Выходные данные: нет

При балансировке структуры происходит усреднение количество элементов в статических массивах. В результате остаются массивы 2-х размеров: n1 и  n2. Количество массивов (элементов списка) 1-го вида kn1, 2-го вида – kn2. Эти параметры определяются следующим образом:

n1=nelems/nlist;                                      

n2=n1+1;

kn1=n2*nlist-nelems;

kn2=nlist-kn1;

где nelems – общее количество элементов в структуре, nlist – количество элементов списка.

Процесс балансировки состоит в том, что формируется новая структура с определенными выше параметрами, одновременно с этим происходит переписывание данных из старой структуры, и ее удаление. Данный процесс происходит в цикле, на каждой итерации которого происходит сдвиг на следующий элемент данных в старом и новых списках. Позиция в каждом из списков задается указателем на элемент списка (curnew, curold) и номером в массиве элемента списка (inew, iold). При переходе на следующий элемент нового списка, создается  новый элемент. А при переходе в старом списке, удаляется предыдущий элемент. Важно отметить, что при переписывании элементов, происходит только присваивание указателей, над самими данными никаких действий не совершается. 

В основной программе  представлены основные возможности работы с классом-шаблоном. За базовый тип берется класс строк CMyString.

Класс-строка имеет следующий интерфейс

/* класс строки */

class CMyString {

      int   l;                                 /* длинна строки */

      char  *s;                                /* строка */

public:

      CMyString() { l=0; s=NULL; };            /* конструктор по умолчанию */

      CMyString(char *str);             

      CMyString(CMyString & str);              /* конструктор копирования */

      ~CMyString();                     

      CMyString &operator=(CMyString &str);    /* оператор присваивания */

      int operator>(CMyString &str);           /* операторы сравнения */

      int operator<(CMyString &str);

      /* операторы ввода-вывода (работа с потоками) */

      friend istream &operator>>(istream &in, CMyString &str);

      friend ostream &operator<<(ostream &out, CMyString &two);

};

В данном классе определены все необходимые операторы для демонстрации возможностей класса-шаблона ClistArr : оператор присваивания, сравнения, ввода из потока и вывода в поток.

Функция балансировки

Void Show();                                       

Входные данные: нет

Выходные данные: нет

Метод вывода всего содержимого на экран. Сначала мы позиционируемся на начало списка и выводим все объекты списка на экран. Так же с помощью этого метода мы можем отслеживать правильно ли выполняется тот или иной метод, для этого необходимо лишь вызвать этот метод после выполнения  какого либо метода.