Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по лабораторной работе №2.doc
Скачиваний:
41
Добавлен:
02.05.2014
Размер:
108.03 Кб
Скачать

14

Методические указания к лабораторной работе

“создание списковых структур данных”

по дисциплине “технология программирования”

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 * совместим по операции присваивания с указателем на объект любого типа.

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