Очередь.
Очередь — это линейный список информации, работа с которой происходит по принципу "первым пришел — первым вышел" (first-in, first-out); этот принцип (и очередь как структура данных) иногда еще называется FIFO. Это значит, что первый помещенный в очередь элемент будет получен из нее первым, второй помещенный элемент будет извлечен вторым и т.д. Это единственный способ работы с очередью; произвольный доступ к отдельным элементам не разрешается.
Чтобы представить себе работу очереди, давайте введем две функции: qstore() и qretrieve() (от "store"— "сохранять", "retrieve" — "получать"). Функция qstore() помещает элемент в конец очереди, а функция qretrieve() удаляет элемент из начала очереди и возвращает его значение. В таблице показано действие последовательности таких операций.
|
|
Действие |
Содержимое очереди |
qstore(A) |
A |
qstore(B) |
А В |
qstore(C) |
A B C |
qretrieve() возвращает А |
В С |
qstore(D) |
B C D |
qretrieve() возвращает В |
C D |
qretrieve() возвращает С |
D |
Следует иметь в виду, что операция извлечения удаляет элемент из очереди и уничтожает его, если он не хранится где-нибудь в другом месте. Поэтому после извлечения всех элементов очередь будет пуста.
В программировании очереди применяются при решении многих задач. Один из наиболее популярных видов таких задач — симуляция. Очереди также применяются в планировщиках задач операционных систем и при буферизации ввода/вывода.
Пример:
/* Мини-планировщик событий */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define MAX 100
char *p[MAX], *qretrieve(void);
int spos = 0;
int rpos = 0;
void enter(void), qstore(char *q), review(void), delete_ap(void);
int main(void)
{
char s[80];
register int t;
for(t=0; t < MAX; ++t) p[t] = NULL; /* иницилизировать массив
пустыми указателями */
for(;;) {
printf("Ввести (E), Список (L), Удалить (R), Выход (Q): ");
gets(s);
*s = toupper(*s);
switch(*s) {
case 'E':
enter();
break;
case 'L':
review();
break;
case 'R':
delete_ap();
break;
case 'Q':
exit(0);
}
}
return 0;
}
/* Вставка в очередь новой встречи. */
void enter(void)
{
char s[256], *p;
do {
printf("Введите встречу %d: ", spos+1);
gets(s);
if(*s==0) break; /* запись не была произведена */
p = (char *) malloc(strlen(s)+1);
if(!p) {
printf("Не хватает памяти.\n");
return;
}
strcpy(p, s);
if(*s) qstore(p);
} while(*s);
}
/* Просмотр содержимого очереди. */
void review(void)
{
register int t;
for(t=rpos; t < spos; ++t)
printf("%d. %s\n", t+1, p[t]);
}
/* Удаление встречи из очереди. */
void delete_ap(void)
{
char *p;
if((p=qretrieve())==NULL) return;
printf("%s\n", p);
}
/* Вставка встречи. */
void qstore(char *q)
{
if(spos==MAX) {
printf("List Full\n");
return;
}
p[spos] = q;
spos++;
}
/* Извлечение встречи. */
char *qretrieve(void)
{
if(rpos==spos) {
printf("Встречь больше нет.\n");
return NULL;
}
rpos++;
return p[rpos-1];
}
