- •СТРУКТУРЫ ДАННЫХ И АЛГОРИТМЫ
- •Глава 1 Линейные списки
- •Понятие структуры данных
- •Тип указатель
- •Линейный список
- •Линейный однонаправленный (односвязный) список
- •Линейный двунаправленный (двусвязный) список
- •Практическое задание «Линейные списки»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 2 Структуры данных стек и очередь
- •Понятие структуры данных стек и очередь
- •Структура данных стек
- •Структура данных очередь
- •Пример решения задачи с использованием стека
- •Практическое задание «Стеки и очереди»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 3 Древовидные структуры данных
- •Понятие структуры данных дерево
- •Представление структуры бинарное дерево в памяти
- •Обход дерева
- •Основные операции над деревом
- •Ввод дерева
- •Практическое задание «Бинарные деревья»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 4 Структура данных таблица
- •Понятие структуры данных таблица
- •Представление таблицы в памяти
- •Организация хеш-таблиц
- •Выбор функции расстановки
- •Разрешение коллизии
- •Операции над таблицами
- •Практическое задание «Управление таблицами»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 5 Алгоритмы упорядочения данных
- •Понятие операции упорядочения
- •Алгоритмы упорядочения
- •Сортировка слиянием
- •Основные алгоритмы сортировки посредством сравнений
- •Улучшенные алгоритмы сортировки сравнением
- •Практическое задание «Алгоритмы сортировки»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Библиографический список
Кроме рассмотренных вариантов простых очередей существует понятие очереди с приоритетом. Элемент такой очереди имеет не только значение, но и вес или приоритет этого значения. При включении элемента в очередь с приоритетом сначала отыскивается место элемента в соответствии с его приоритетом. Элемент с наивысшим приоритетом помещается в начало очереди, элемент с низшим весом в конец очереди. Такой очереди наилучшим образом отвечает двусвязный циклический список.
Еще одной разновидностью этих структур данных является дек. Дек – это структурный тип данных, у которого обе позиции: начало и конец списка доступны для добавления и взятия элемента. Таким образом, дек может быть и стеком, и очередью, и комбинацией этих структур. Наиболее часто дек представляется структурой с ограничением на вход или выход: дек с ограничением на вход – только одна позиция доступна для добавления элемента, дек с ограничением на выход – только одна позиция доступна для взятия элемента из дека.
Пример решения задачи с использованием стека
Условие задачи: дана последовательность литер, являющаяся записью арифметического выражения. Последовательность оканчивается точкой (размер последовательности неизвестен). В записи выражения используются два вида скобок: круглые и квадратные. Требуется проверить выполнение баланса скобок. Баланс скобок соблюдается, если:
1)справа от каждой открывающей скобки есть закрывающая скобка;
2)слева от каждой закрывающей скобки есть открывающая скобка;
3)соответствующие парные скобки (круглые, квадратные) правильно вложены друг в друга.
Пример правильно записанного выражения:
a+[(x+y)*(x+2)]/[[3+abs(x)]+d/(a-b)]
56
Так как размер последовательности неизвестен, то обрабатывать последовательность будем частями, единицей обработки будет символ. По одному текущему символу нельзя установить соответствие парных скобок, поэтому обработку символа открывающая скобка приходится отложить до момента появления закрывающей скобки. Условия баланса скобок будут выполнены, если текущей закрывающей скобке предшествует ближайшая парная открывающая скобка, поэтому открывающие скобки необходимо откладывать в стек, а при появлении закры-
вающей скобки брать из стека отложенную открывающую скобку.
Программа решения задачи
struct list
{
char elem; list *next;
};
typedef list stack;
stack *push(char c, stack *s)
{
stack *p = new stack; p->elem = c;
p->next= s; return p;
}
int pop(char *c, stack **s)
{
if (*s)
{
stack *p = *s; *c = (*s)->elem; *s = (*s)->next; delete p;
return 1;
57
}
return 0;
}
void main()
{
char sym = 0, ch = 0, b = 1; stack *s = NULL;
scanf("%c", &sym); while (sym != '.' && b)
{
if (sym == '(' || sym == '[') s = push(sym, s);
else
if (sym == ')' || sym == ']') if (pop(&ch, &s))
if (sym == ')') b = ch == '(';
else
b = ch == '['; else b = 0;
scanf ("%c", &sym);
}
b && s == NULL ?
printf("Баланс скобок есть.") : printf("Баланса скобок нет.");
}
ПРАКТИЧЕСКОЕ ЗАДАНИЕ «СТЕКИ И ОЧЕРЕДИ»
Цели
Изучить основные способы организации структур данных стек и очередь. Сформировать практические навыки использования стеков и очередей при решении задач.
58
Варианты заданий
Написать операции работы с заданной структурой данных, включив их в один модуль (файл). К основным операциям добавить операцию, показывающую содержимое структуры после выполнения какого-либо действия с ней. Эту операцию реализовать на основе базовых операций:
а) основные операции над статическим стеком; б) основные операции над динамическим стеком;
в) операция “принадлежит ли заданный элемент” статическому стеку;
г) операция “принадлежит ли заданный элемент” динамическому стеку;
д) основные операции над статической очередью (вид очереди:
а, б, в, г );
е) основные операции над динамической очередью (вид очереди: а, б);
ж) операция “добавить элемент в очередь” для статической очереди с приоритетом (вид очереди: а, б, в, г). На вход такой очереди подается элемент и его приоритет, определяющий место элемента в очереди. В очереди с приоритетом элементы должны располагаться в порядке возрастания или убывания приоритетов;
з) операция “добавить элемент в очередь” для динамической очереди с приоритетом (вид очереди: а, б ) – см. ж);
и) операция “принадлежит ли заданный элемент” статической очереди (вид очереди а, б, в, г);
к) операция “принадлежит ли заданный элемент” динамической очереди (вид очереди: а, б);
л) основные операции над статическим деком; м) основные операции над динамическим деком.
59
