Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2 лекция АиСД.docx
Скачиваний:
19
Добавлен:
27.11.2019
Размер:
353 Кб
Скачать

Очереди

Очередь – это структура данных, представляющая собой последовательность элементов, образованная в порядке их поступления. Каждый новый элемент размещается в конце очереди; элемент, стоящий в начале очереди, выбирается из нее первым. В очереди используется принцип доступа к элементам FIFO ( First Input – First Output, "первый пришёл – первый вышел") (рис. 30.2). В очереди доступны два элемента (две позиции): начало очереди и конец очереди. Поместить элемент можно только в конец очереди, а взять элемент только из ее начала. Примером может служить обыкновенная очередь в магазине.

Рис. 30.2.  Очередь и ее организация

Описание очереди выглядит следующим образом:

struct имя_типа {

информационное поле;

адресное поле1;

адресное поле2;

};

где информационное поле – это поле любого, ранее объявленного или стандартного, типа;

адресное поле1, адресное поле2 – это указатели на объекты того же типа, что и определяемая структура, в них записываются адреса первого и следующего элементов очереди.

Например:

1 способ: адресное поле ссылается на объявляемую структуру.

struct list2 {

type pole1;

list2 *pole1, *pole2;

}

2 способ: адресное поле ссылается на ранее объявленную структуру.

struct list1 {

type pole1;

list1 *pole2;

}

struct ch3 {

list1 *beg, *next ;

}

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

Описание элементов очереди аналогично описанию элементов линейного двунаправленного списка. Поэтому объявим очередь через объявление линейного двунаправленного списка:

struct Queue {

Double_List *Begin;//начало очереди

Double_List *End; //конец очереди

};

. . . . . . . . . .

Queue *My_Queue;//указатель на очередь

Основные операции, производимые с очередью:

  • создание очереди;

  • печать (просмотр) очереди;

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

  • извлечение элемента из начала очереди;

  • проверка пустоты очереди;

  • очистка очереди.

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

//создание очереди

void Make_Queue(int n, Queue* End_Queue){

Make_Double_List(n,&(End_Queue->Begin),NULL);

Double_List *ptr; //вспомогательный указатель

ptr = End_Queue->Begin;

while (ptr->Next != NULL)

ptr = ptr->Next;

End_Queue->End = ptr;

}

//печать очереди

void Print_Queue(Queue* Begin_Queue){

Print_Double_List(Begin_Queue->Begin);

}

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

void Add_Item_Queue(int NewElem, Queue* End_Queue){

End_Queue->End = Insert_Item_Double_List(End_Queue->End,

0, NewElem)->Next;

}

//извлечение элемента из начала очереди

int Extract_Item_Queue(Queue* Begin_Queue){

int NewElem = NULL;

if (Begin_Queue->Begin != NULL) {

NewElem = Begin_Queue->Begin->Data;

Begin_Queue->Begin=Delete_Item_Double_List(Begin_Queue->Begin,0);

//удаляем вершину

}

return NewElem;

}

//проверка пустоты очереди

bool Empty_Queue(Queue* Begin_Queue){

return Empty_Double_List(Begin_Queue->Begin);

}

//очистка очереди

void Clear_Queue(Queue* Begin_Queue){

return Delete_Double_List(Begin_Queue->Begin);

}

Пример 2. Дана последовательность ненулевых целых чисел. Признаком конца последовательности является число 0. Найдите среди них первый наибольший отрицательный элемент. Если такого элемента нет, то выведите сообщение об этом.

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

//главная функция

int _tmain(int argc, _TCHAR* argv[]){

int n;

Queue *My_Queue;

My_Queue = new Queue();

Make_Queue(1,My_Queue);

while (My_Queue->End->Data != 0){

cout << "Введите значение ";

cin >> n;

Add_Item_Queue(n,My_Queue);

}

cout << "\nОчередь: \n";

Print_Queue(My_Queue);

Find_Max_Negative_Element(My_Queue);

system("pause");

return 0;

}

//функция поиска первого наибольшего отрицательного элемента

void Find_Max_Negative_Element(Queue* Begin_Queue){

int tmp;

int max=Extract_Item_Queue(Begin_Queue);

while (Begin_Queue->Begin->Data != 0) {

tmp = Extract_Item_Queue(Begin_Queue);

if (max > 0 || tmp < 0 && abs(tmp) < abs(max))

max = tmp;

}

if (max > 0) printf("Элементов нет!");

else printf("Есть такой элемент: %d", max);

}