Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТП лаб1.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
109.57 Кб
Скачать

12

1 Цель работы

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

2 Краткие теоретические сведения

Во многих задачах требуется использовать данные, представление которых (конфигурация, размеры, состав) может изменяться в процессе выполнения программы. О таких изменяемых данных говорят, используя принятый в информатике термин "динамические информационные структуры ". Динамические структуры имеют следующие основные особенности:

  • непостоянство и непредсказуемость размера (числа элементов) структуры в процессе ее обработки. Число элементов структуры может изменяться от нуля до значений, определяемых спецификой решения задачи или доступным размером памяти;

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

Часто динамические структуры физически представляются в форме связных списков. Связный список – такая структура данных, элементами которой служат записи с одним и тем же форматом, связанные друг с другом с помощью указателей, хранящихся в самих элементах списка.

2.1 Односвязный список

Наиболее простая динамическая информационная структура - это односвязный список, элементами (звеньями) которого служат объекты, например, такого структурного типа:

struct имя_структурного_типа

{

элементы _структуры; /* данные */

struct имя_структурного_типа * указатель;

};

В каждую структуру такого типа входят: содержательные элементы структуры которые хранят информацию об однотипных объектах предметной области ( будем их называть просто ”данные” и обозначать D), и указатель на другой объект того же типа, что и определяемая структура ( будем обозначать эту часть структуры L).

Чтобы продемонстрировать некоторые особенности обработки простых динамических информационных структур, разработаем программу, в которой определим структурный тип для представления звеньев односвязного списка и решим такую простейшую задачу: "Ввести с клавиатуры произвольное количество структур, объединяя их в односвязный список, а затем вывести на экран дисплея содержимое введенного списка в порядке формирования его звеньев".

Анализ динамических информационных структур удобнее всего выполнять с помощью их графического изображения. На рисунке 1 приведены схема односвязного списка и обозначения, которые будут использованы в программе. Для работы со списком понадобятся три указателя: beg - на начало списка; end - на последний элемент, уже включенный в список; rex - указатель для "перебора" элементов списка от его начала.

Начало списка

beg

. . .

rex

. . .

end

(Последний элемент списка)

Рисунок 1 - Односвязный динамический список

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

#include <stdlib.h>

#include <stdio.h>

/* Определение структурного типа "Звено списка":*/

struct cell {

char sign [10];

int weight;

struct cell * pc;

};

void main()

{/* Указатель для перебора звеньев списка: */

struct cell * rex;

struct cell * beg=NULL; /* Начало списка */

struct cell * end=NULL; /* Конец списка */

printf("\nВведите значения структур:\n");

/* Цикл ввода и формирования списка */

do

{ /* Выделить память для очередного звена списка: */

rex=(struct cell *)malloc(sizeof(struct cell));

/* Ввести значения элементов звена: */

printf("sign=") ;

scanf("%s",& rex->sign) ;

printf("weight=") ;

scanf("%d",& rex->weight);

if (rex->weight = = 0)

{

free(rex) ;

break; /* Выход из цикла ввода списка */

}/* Включить звено в список: */

if (beg==NULL && end==NULL)

/*Список пуст – включить введенный элемент в список первым*/

beg=rex;

else /* Включить звено в уже существующий список */ ;

end->pc=rex;

end=rex ;

end->pc=NULL ;

}

while(1) ; /* Конец ввода списка */

printf("\nСодержимое списка:") ; /* Напечатать список */

rex=beg;

while (rex!=NULL)

{

printf("\nsign=%s\tweight=%d",rex->sign,rex->weight) ;

rex=rex->pc;

}

}

Пример выполнения программы:

Введите данные о структурах:

Sign=sigma

weight=16

Sign=omega

weight=44

Sign=alfa

weight=0

Содержимое списка:

Sign=sigma weight=16

Sign=omega weight=44

Обратите внимание, что при вводе данных о третьем элементе списка введено нулевое значение переменной weight и соответствующий элемент в список не включен.

В программе ввод данных, т.е. заполнение односвязного списка структур, выполняется в цикле. Условием окончания цикла служит нулевое значение, введенное для элемента int weight очередной структуры.

Формирование списка структур происходит динамически. Указатели-beg, end инициализированы нулевыми значениями - вначале список пуст.

Обратите внимание на преобразование типов (struct cell *) при выделении памяти для структуры типа struct cell. Функция malloc() независимо от типа параметров всегда возвращает указатель типа void *, а слева от знака присваивания находится указатель rex типа struct cell *. Используется явное приведение типов, хотя это не обязательно - тип void * совместим по операции присваивания с указателем на объект любого типа.

Остальные особенности программы поясняются комментариями в ее тексте.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]