- •Методические указания к лабораторной работе
- •2.1 Односвязный список.
- •2.2.Рекурсия при обработке односвязного списка.
- •Все-если
- •2.3 Двусвязный список
- •2.2.Рекурсия при обработке двусвязного списка.
- •3 Методика выполнения лабораторной работы
- •4 Содержание отчета
- •5 Литература
- •6 Рекомендуемые задания к лабораторной работе
Методические указания к лабораторной работе
“создание списковых структур данных”
по дисциплине “технология программирования”
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 * совместим по операции присваивания с указателем на объект любого типа.
Остальные особенности программы поясняются комментариями в ее тексте.