Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методички.C++ / Конспект Лекций - Части 1,2.pdf
Скачиваний:
275
Добавлен:
24.02.2016
Размер:
1.97 Mб
Скачать

5. Динамическая структура данных – ОЧЕРЕДЬ

Очередь – упорядоченный набор данных (структура данных), в котором в отличие от стека извлечение данных происходит из начала цепочки, а добавление данных – в конец этой цепочки.

Очередь также называют структурой данных, организованной по принципу FIFO (First In, First Out) – первый вошел (первый созданный элемент очереди), первый вышел.

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

Пример очереди – некоторый механизм обслуживания, который может выполнять заказы только последовательно один за другим. Если при поступлении нового заказа данное устройство свободно, оно немедленно приступит к выполнению этого заказа, если же оно выполняет какой-то ранее полученный заказ, то новый заказ поступает в конец очереди из других ранее пришедших заказов. Когда устройство освобождается, оно приступает к выполнению заказа из начала очереди, т.е. этот заказ удаляется из очереди и первым в ней становится следующий за ним заказ.

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

Работу с очередью можно организовать двумя способами.

1.Использовать помимо рабочего указателя для начала и окончания очереди дополнительные переменные-указатели, т.е. первый указатель установить на начало очереди, а второй – на ее конец.

2.Использовать указатель-переменную только для начала очереди, а перемещаться по ней на основе внутренних связей между ее элементами.

Основные операции с очередью следующие:

– первоначальное формирование очереди;

– добавление нового элемента в конец очереди;

– удаление элемента из начала очереди.

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

Далее мы организуем структуру данных следующего вида:

begin

 

 

 

 

 

 

end

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

info1

A1

 

 

 

info2

A2

 

 

. . .

 

 

 

infoN

NULL

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

где каждый элемент очереди имеет информационную infо и адресную Next (A1,A2

...) части.

Шаблон элемента структуры (аналогично стеку) может иметь такой вид: struct Spis {

120

int info; Spis *Next;

} *begin, *end;

begin, end – указатели на начало и конец очереди.

Формирование очереди

Первоначальное формирование очереди осуществляется в два этапа.

Этап 1. Первоначальное формирование очереди

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

1)ввести информацию для первого элемента (для простоты – это какое-то целое положительное число – значение переменной i);

2)захватить, используя рабочий указатель память под первый элемент:

t = new Spis;

сформирован конкретный адрес (А1) для первого элемента; 3) в информационную часть заносим введенную с клавиатуры информа-

цию:

t -> info = i; ( обозначим ее как i1 ) 4) в адресную часть заносим NULL:

t -> Next = NULL;

5) указателям на начало и на конец очереди присваиваем значение t: begin = end = t;

На этом этапе получили следующее: begin

infо = i1

Next = NULL

end

Этап 2. Формирование элементов очереди, начиная с первого

Рассмотрим только для второго элемента, а ниже обобщим для произвольного числа элементов.

1.Начало бесконечного цикла while (1), окончанием которого будет отрицательное число.

2.Ввод информации для текущего элемента – значение i .

3.Если значение не подходит, т.е. i<0 – завершение цикла (break).

4.Иначе захватываем память под текущий элемент:

t = new Spis;

5.Формируем информационную часть (для второго элемента введенное значение обозначим i2):

t -> info=i;

6.В адресную часть созданного элемента (текущего) – NULL, т.к. этот элемент теперь последний:

t -> Next = NULL;

121

7.Элемент добавляется в конец очереди, поэтому в адресную часть последнего элемента end ->Next вместо NULL заносим адрес созданного:

end -> Next = t;

бывший последний элемент теперь стал предпоследним.

8.Переставляем указатель последнего элемента на добавленный:

end = t; 9. Конец цикла

В результате получим:

t

begin

 

i1 Next = t

 

 

i2

Next = NULL

 

 

 

end

Алгоритм добавления нового элемента

1.Захватываем память под новый элемент структуры.

2.Устанавливаем на него через указатель конца очереди указатель теперь уже предпоследнего элемента:

end -> Next = t;

3.Считываем данные и заносим в информационную часть.

4.Записываем в адресную часть NULL.

5.Устанавливаем на новый элемент указатель конца очереди.

Графически это выглядит так:

. . .

 

 

end

 

 

 

 

t

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

info =in

NULL

 

 

 

 

info =in+1

Next

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

. . .

 

 

end

 

 

 

 

t

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

info =in

NULL

 

 

 

 

info =in+1

Next

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

end

. . .

 

 

info =in

Next=t

 

 

 

 

info =in+1

NULL

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Алгоритм удаления первого элемента из очереди

Имеем непустую очередь (можно организовать проверку указателей на

NULL).

1. Устанавливаем текущий указатель на начало очереди: t = begin;

122

2.Обрабатываем информационную часть первого элемента очереди, например, печатаем.

3.Указатель на начало очереди переставляем на следующий (2-ой) элемент

begin = begin->Next;

4.Освобождаем память, захваченную под 1-ый элемент: delete t;

5.Выводим сообщение, например, «Элемент удален!».

Алгоритм просмотра очереди

1.Устанавливаем текущий указатель на начало очереди: t = begin;

2.Начало цикла, выполняющегося пока t != NULL (работает, пока не дойдем до конца очереди).

3.Информационную часть текущего элемента t->info выводим на печать.

4.Переставляем текущий указатель на следующий элемент очереди:

t = t -> Next; 5. Конец цикла.

Алгоритм установки указателя на нужный элемент очереди

1.Ввести номер нужного элемента k.

2.Устанавливаем текущий указатель на начало очереди: t = begin;

3.Начало цикла: перебор элементов от i=1 до i<k с шагом 1.

4.Переставляем текущий указатель на следующий элемент очереди: t = t -> Next;

5.Конец цикла.

Витоге t будет указывать на начало k-го элемента очереди.

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

Текст программы может иметь вид:

#include <stdio.h>

 

#include <conio.h>

 

struct Spis {

// Описание структуры

int info;

 

Spis *Next;

 

} *begin, *end;

 

void Make(int);

// Описание прототипов функций

void Del();

// Удаление одного первого элемента

void Del_All();

// Освобождение всей памяти

void View();

 

void main(void) { Spis *t;

int i; while(1) {

puts("\n Creat - 1\n View - 2\n Add - 3\n Del - 4\n EXIT - 0");

123

switch (getch()) {

case '1': Make(0); break; // kod=0 – Первоначальное формирование case '2': View(); break;

case '3': if(begin == NULL) Make(0);

else Make(1); // kod=1 – Добавление

break;

case '4': Del(); break; case '0': Del_All();return;

}// switch()

}// while(1)

}

 

 

 

//--------------

Создание очереди (kod=0) и Добавление в конец (kod=1)---------

void Make(int kod) {

 

 

Spis *t;

 

 

 

int i;

 

 

 

if ( kod==0 )

{

// Формирование первого элемента

 

printf(" Input info 1: ");

 

scanf("%d", &i);

 

 

t = new Spis;

 

 

t -> info = i;

 

 

t -> Next = NULL;

 

begin = end = t;

 

 

}

 

 

 

while (2)

{

// Добавление положительных элементов

 

printf(" Input info : ( >= 0 ) ");

 

scanf("%d", &i);

 

 

if(i<0) break;

// Выход из цикла while(2)

 

t = new Spis;

 

 

t -> info = i;

 

 

t -> Next = NULL;

 

end -> Next = t;

 

 

end = t;

 

 

 

}

 

 

//

}

Просмотр очереди

 

void View() {

 

 

 

Spis *t = begin;

 

 

puts(" Ochered ");

 

 

if(t == NULL)

{

 

printf("\n NO !");

 

return;

 

 

}

 

 

 

while (t != NULL) {

 

printf("\n

Element %d ", t -> info);

t = t -> Next;

124

Соседние файлы в папке методички.C++