Студопедия — Теоретические сведения. В результате работы исследовались частотные характеристики двух колебательных контуров в зависимости от связи между ними.
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Теоретические сведения. В результате работы исследовались частотные характеристики двух колебательных контуров в зависимости от связи между ними.

СВЯЗНЫЕ СПИСКИ

 

 

Цель работы:изучить теорию и научиться программировать связные списки.

 

 

Теоретические сведения

 

 

Рассмотренные ранее типы данных и работа с ними позволяют писать программы разной степени сложности. Однако существуют задачи, в которых традиционное представление информации на основе переменных, структур, объединений и т.п. является не эффективным. Классическим примером такого рода может стать обработка табличных данных, у которых есть заданные поля, т.е. набор стандартных типов данных, и записи, представляющие собой конкретное наполнение таблицы. Формально для описания таблицы можно использовать простой или динамический массив структур. Но в этом случае возникает несколько проблем. Во-первых, наперед часто сложно указать приемлемое число записей (размер массива) для хранения информации. Во- вторых, при большом размере массива сложно выполнять добавление и удаление записей, находящихся между другими записями таблицы. И, наконец, любой используемый массив не будет эффективно использовать память ЭВМ, т.к. всегда будут зарезервированы не используемые записи на случай добавления новых. Эти основные проблемы обусловили необходимость создания нового механизма представления данных в памяти ЭВМ, который получил название связные списки.

Идея связных списков состоит в представлении данных в виде объектов,

связанных друг с другом указателями (рис. 4).

 

 


*head


*current


*tail


 

 


NULL


*prev

Объект 1

*next


*prev

Объект 2

*next


*prev

… Объект N

*next NULL


 

Рис. 4. Графическая интерпретация связных списков

 

 

Здесь *prev и *next – указатели на предыдущий и следующий объекты соответственно; *head и *tail – указатели на первый и последний объекты;

*current – указатель на текущий объект, с которым идет работа. Если предыдущего или последующего объекта не существует, то указатели *prev и

*next принимают значение NULL. Указатели *head и *tail являются

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


название автор год издания

lib lib.title lib.author lib.year

 

 

lib lib.title lib.author lib.year

 

 

lib lib.title lib.author lib.year

#

lib lib.title lib.author lib.year

 

 

Строки данной таблицы можно описать с помощью структуры:

 

 

typedef struct tag_lib {

char title[100]; char author[100]; int year;

} LIB;

 

 

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

 

 

typedef struct tag_obj { LIB lib;

LIB* prev, *next;

} OBJ;

 

 

Здесь *prev и *next – указатели на предыдущую и следующую строки соответственно.

По умолчанию указатели head и tail равны NULL:

 

 

OBJ* head = NULL, *tail = NULL;

 

 

При добавлении записей выполняется инициализация этих указателей, а также

prev и next внутри объектов:

 

 

OBJ* add_obj(char* title, char* author, int year)

{

OBJ* current = (OBJ *)malloc(sizeof(OBJ)); strcpy(current->lib.title, title); strcpy(current->lib.author, author); current->lib.year = year;

current->prev = tail;

current->next = NULL;

if(tail!= NULL) tail->next = current;

if(head == NULL) head = current;


tail = current;

return current;

}

 

Данная функция использует три параметра для ввода данных в структуру LIB. В первой строке функции создается новая структура типа OBJ. Во второй, третьей и четвертой строках осуществляется запись информации в структуру LIB. Затем, инициализируются указатели prev и next добавленного объекта. Учитывая, что добавление осуществляется в конец списка, то указатель next должен быть равен NULL, а указатель prev указывать на предыдущий объект, т.е. быть равен указателю tail. В свою очередь, объект, на который указывает указатель tail, становится предпоследним и его указатель next должен указывать на последний объект, т.е. быть равным указателю current. Затем проверяется, является ли добавляемый объект первым (head == NULL), и если это так, то указатель head приравнивается указателю current. Наконец, указатель tail инициализируется на последний объект. Последняя строка функции возвращает указатель на созданный объект.

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

 

 

OBJ* del_obj(OBJ* current)

{

if(current == head)

if(current->prev!= NULL) head = current->prev;

else head = current->next;

if(current == tail)

if(current->next!= NULL) tail = current->next;

else tail = current->prev;

if(current->prev!= NULL)

current->prev->next = current->next;

if(current->next!= NULL)

current->next->prev = current->prev;

free(current);

return head;

}

 

Функция del_obj() в качестве аргумента использует указатель на объект, который следует удалить. Сначала выполняется проверка для инициализации указателя head, в том случае, если удаляется первый объект, на который он указывает. Аналогичная проверка осуществляется для tail. Затем осуществляется проверка: если предыдущий объект относительно текущего существует, то его указатель на следующий объект следует переместить. Аналогичная проверка выполняется и для следующего объекта относительно удаляемого. После настройки всех указателей вызывается функция free() для удаления объекта из памяти и возвращается указатель на первый объект.

Введенные функции в программе можно использовать следующим образом:


int main()

{

OBJ *current = NULL;

int year;

char title[100], author[100];

do

{

printf("Введите название книги: ");

scanf("%s",title); printf("Введите автора: "); scanf("%s",author); printf("Введите год издания: "); scanf("%d",&year);

current = add_obj(title,author,year);

printf("Для выхода введите 'q'");

} while(scanf("%d",&year) == 1);

current = head;

while(current!= NULL)

{

printf("Title: %s, author %s, year = %d\n",

current->lib.title, current->author.old, current->lib.year);

current = current->next;

}

while(head!= NULL)

del_obj(head);

return 0;

}

Функция main() осуществляет ввод названия книги, автора и года издания в цикле do while(). Там же вызывается функция add_obj() с соответствующими

параметрами, которая формирует связанный список на основе введенных данных. Пользователь выполняет ввод до тех пор, пока не введет какой либо символ на последний запрос. В результате цикл завершится, и указатель current

передвигается на первый объект. Затем, в цикле while осуществляется вывод информации текущего объекта на экран, а указатель current передвигается на следующий объект. Данная процедура выполняется до тех пор, пока указатель

не станет равным NULL, что означает достижение конца списка. Перед выходом из программы связный список удаляется с помощью функции del_obj(), у которой в качестве аргумента всегда используется указатель head.

Если данный указатель принимает значение NULL, то это означает, что связный список пуст и не содержит ни одного объекта. После этого программа завершает свою работу.

 




<== предыдущая лекция | следующая лекция ==>
Основные расчетные формулы. Полоса пропускания системы вычисляется по следующим выражениям | Задания к тексту

Дата добавления: 2015-08-27; просмотров: 233. Нарушение авторских прав; Мы поможем в написании вашей работы!



Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

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

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Мелоксикам (Мовалис) Групповая принадлежность · Нестероидное противовоспалительное средство, преимущественно селективный обратимый ингибитор циклооксигеназы (ЦОГ-2)...

Менадиона натрия бисульфит (Викасол) Групповая принадлежность •Синтетический аналог витамина K, жирорастворимый, коагулянт...

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

ИГРЫ НА ТАКТИЛЬНОЕ ВЗАИМОДЕЙСТВИЕ Методические рекомендации по проведению игр на тактильное взаимодействие...

Реформы П.А.Столыпина Сегодня уже никто не сомневается в том, что экономическая политика П...

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

Studopedia.info - Студопедия - 2014-2024 год . (0.01 сек.) русская версия | украинская версия