- •СТРУКТУРЫ ДАННЫХ И АЛГОРИТМЫ
- •Глава 1 Линейные списки
- •Понятие структуры данных
- •Тип указатель
- •Линейный список
- •Линейный однонаправленный (односвязный) список
- •Линейный двунаправленный (двусвязный) список
- •Практическое задание «Линейные списки»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 2 Структуры данных стек и очередь
- •Понятие структуры данных стек и очередь
- •Структура данных стек
- •Структура данных очередь
- •Пример решения задачи с использованием стека
- •Практическое задание «Стеки и очереди»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 3 Древовидные структуры данных
- •Понятие структуры данных дерево
- •Представление структуры бинарное дерево в памяти
- •Обход дерева
- •Основные операции над деревом
- •Ввод дерева
- •Практическое задание «Бинарные деревья»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 4 Структура данных таблица
- •Понятие структуры данных таблица
- •Представление таблицы в памяти
- •Организация хеш-таблиц
- •Выбор функции расстановки
- •Разрешение коллизии
- •Операции над таблицами
- •Практическое задание «Управление таблицами»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Глава 5 Алгоритмы упорядочения данных
- •Понятие операции упорядочения
- •Алгоритмы упорядочения
- •Сортировка слиянием
- •Основные алгоритмы сортировки посредством сравнений
- •Улучшенные алгоритмы сортировки сравнением
- •Практическое задание «Алгоритмы сортировки»
- •Задачи для самостоятельной работы
- •Контрольные вопросы
- •Библиографический список
ГЛАВА 2 СТРУКТУРЫ ДАННЫХ СТЕК И ОЧЕРЕДЬ
Понятие структуры данных стек и очередь
Стек – это структурный тип данных, у которого доступен один элемент (одна позиция). Этот элемент называется вершиной стека. Взять элемент из стека можно только из вершины. Добавить элемент в стек можно только в вершину. Таким образом, вершина стека – это последний помещенный в стек элемент. С помощью структуры данных стек реализуется правило обработки данных (принцип или дисциплина обслуживания) называемое: последний вошел – первый вышел (Last In
– First Out).
Очередь – это структурный тип данных, у которого доступны два элемента (две позиции): начало и конец очереди. Поместить элемент можно только в конец очереди, а взять элемент – только из ее начала. Таким образом, начало очереди – это первый помещенный элемент, а конец –последний помещенный элемент. С помощью структуры данных очередь реализуется правило обработки данных называемое: первый вошел – первый вышел (First In – First Out).
Стек или очередь используются тогда, когда при обработке множества данных по тем или иным причинам нельзя обработать текущие данные (данные, к которым есть доступ), приходится отложить обработку этих данных до тех пор, пока не возникнет ситуация, когда это будет возможно. Сами данные (или информация о них) помещаются в стек или в очередь. Стек и / или очередь используются, как правило, для хранения промежуточных данных задачи или части входных данных.
Перед использованием значение структуры данных стек или очередь обязательно должно быть инициализировано значением «пусто».
Стеки и очереди могут быть организованы различными способами. При этом они могут быть размещены как в статической памяти, так и в динамической.
43
Структура данных стек
Стек с несвязным представлением, отображаемый в статической памяти, будем называть статический стек. В статической памяти стек можно представить как множество данных, которые располагаются в стеке последовательно и непрерывно друг за другом и это множество дополнено информацией, которая позволяет вносить изменения в динамическую структуру данных, это, прежде всего информация о количестве элементов в стеке. При задании такого стека вносится ограничение на размер стека. Его можно задать следующим образом:
struct stack
{
int top; type data[n];
};
Здесь type – тип элементов, хранимых в стеке. Поле top определяет вершину стека (точнее позицию вершины стека). Поле top позволяет определить состояние стека: пуст, полон, один элемент и т. п. Ограничение на количество элементов в массиве (константа n) задает размер стека.
top |
0 |
|
|
|
K |
n - 1 |
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
• • • |
|
|
|
• • • |
|
|
|
|
|
|
вершина |
|
|
||
Вершина стека – это либо позиция стека (массива), куда был помещен последний элемент, либо позиция, куда будет помещен очередной элемент.
Ввести в употребление переменную типа стек можно следующим образом:
stack s;
44
Для инициализации статического стека (задать начальное значение стека) достаточно определить такое начальное значение поля top, которое показывало бы, что в стеке еще нет элементов, т. е. стек пуст. Если s.top = -1 (или 0 в случае, когда top показывает на позицию, куда будет помещен очередной элемент), то стек пуст. В таком случае при помещении в стек элемента значение s.top увеличивается на единицу, при взятии элемента уменьшается на единицу. Если top равно n - 1 (или n), то стек полон, добавить еще один элемент нельзя. Если указатель равен 0 (или 1), то в стеке один элемент. При взятии из стека единственного элемента, он становится пустым, поле top должно получить значение -1 (или 0).
Обращение к элементу в вершине статического стека: s.data[s.top]. Стек со связным представлением, отображаемый в динамической
памяти, будем называть динамический стек. Его можно задать линейным односвязным списком:
struct list
{
type elem; list *next;
};
typedef list stack;
В стеке, представленном линейным односвязным списком, вершина стека – первый элемент списка (но последний помещенный в стек).
вершина стека
. |
|
NULL |
|
|
|
|
|
|
Объявить переменную типа стек можно следующим образом:
stack *s;
45
Переменная s – это указатель на вершину стека. Для инициализации динамического стека, т. е. создания пустого динамического стека, достаточно указателю на вершину стека задать значение NULL: s = NULL. Обращение к значению элемента в вершине динамического стека: s ->elem.
Основные операции над стеком:
1)положить элемент в стек;
2)взять элемент из стека;
3)проверить состояние стека – пуст стек?
4)создать стек.
Примеры операций над статическим стеком:
struct stack
{
int top; char el[n];
};
- операция создать стек состоит в инициализации стека пустым значением (выделение памяти под стек осуществляется в вызывающей подпрограмме)
void create(stack *s)
{
s->top = -1;
}
- операция проверить стек на пустоту
int empty(stack s)
{
return s.top == -1;
}
46
- операция положить элемент в стек
int push(char c, stack *s)
{
if (s->top != n - 1)
{
s->el[s->top++] = c; return 1;
}
else
return 0;
}
- операция взять элемент из стека
int pop(char *c, stack *s)
{
if (empty(*s))
{
*x = s->el[s->top]; s->top--;
return 1;
}
return 0;
}
Примеры операций над динамическим стеком:
struct list
{
char elem; list *next;
};
typedef list stack;
47
- операция положить элемент в стек
stack *push(char c, stack *s)
{
stack *p = new stack; p->elem = c;
p->next = s; return p;
}
- операция взять элемент из непустого стека
stack *pop(char *c, stack *s)
{
stack *p = s; *c = s->elem; s = s->next; delete p; return s;
}
- операция взять элемент из стека (возможно пустого)
int pop(char *c, stack **s)
{
if (*s)
{
stack *r = *s; *x = (*s)->elem; *s = (*s)->next; delete r;
return 1;
}
return 0;
}
48
