- •Базовые понятия информатики. Понятие «Информатика» и «Информация»
- •Информация
- •Информационные технологии
- •Понятие алгоритма. Свойства и классы алгоритмов. Формы представления алгоритмов
- •Понятие алгоритма. Базовые алгоритмические структуры
- •Представление данных в памяти персонального компьютера.
- •Принципы обработки программных кодов
- •Компиляторы
- •Интерпретатор
- •Язык с. История развития. Основные свойства языка
- •Отличительные особенности языкаC
- •Элементы языка c
- •Константы
- •Базовые типы данных
- •Директива #include
- •Использование void
- •Инструкция return
- •Описание переменных
- •Обработка данных. Операторы
- •Арифметические операторы
- •Приоритет операторов и порядок вычислений
- •Используемые алгоритмы обработки данных
- •Аккумуляторы
- •Преобразования типов данных
- •Декларации и дефиниции функций
- •Формальные и фактические параметры. Вызов функций
- •Возврат функцией значений
- •Переменные в функциях
- •Автоматические (локальные) переменные
- •Внешние (глобальные) переменные
- •Статические переменные
- •Передача параметров по значению
- •Передача параметров по ссылке
- •Значения параметров по умолчанию
- •Перегрузка функций
- •Рекурсия
- •Встроенные функции
- •Обработка символьных данных
- •Функция puts()
- •Функция putchar()
- •Функция printf()
- •Выбор правильных средств вывода информации
- •Функция gets()
- •Функция getchar()
- •Функция scanf()
- •Выбор соответствующих средств ввода данных
- •Управляющие структуры Структуры выбора (if / else)
- •Структуры выбора (switch/case/default)
- •Структуры повторения (циклы)
- •Использование цикла for
- •Использование цикла do...While (постусловие)
- •Использование цикла while (предусловие)
- •Операторы передачи управления Оператор безусловного перехода goto
- •Оператор break
- •Оператор continue
- •Препроцессор языка Си
- •Массивы Объявление переменной массива
- •Использование индексной переменной
- •Инициализация массива при объявлении
- •Передача массивов в функции
- •Использование констант при объявлении массивов
- •Символьные строки
- •Массивы строк
- •Алгоритмы сортировки массива
- •Поиск заданного элемента в массиве
- •Указатели
- •Объявление указателя
- •Указатели на массивы
- •Операции над указателями
- •Указатели на строку
- •Указатели на функцию
- •Функции, возвращающие указатель
- •Указатели на многомерные массивы
- •Массивы указателей
- •Динамическое распределение памяти
- •Структуры данных
- •Реализация одних структур на базе других
- •Очередь
- •Операции над очередями
- •Операции над стеками
- •Ссылочные реализации структур данных
- •Операции над списками
Структуры данных
Структуры данных представляют собой набор некоторым образом сгруппированных данных. Простейшим примером структуры данных служит массив.
Все элементы массива являются равнодоступными, а при решении некоторых задач возникает необходимость работать с данными в том или ином порядке. Для этого служат такие структуры данных, как очереди, стеки и списки.
Реализация одних структур на базе других
Реализация структуры данных на основе базовой структуры — это описание ее работы в терминах базовой структуры. При этом считается, что базовая структура либо дана изначально, либо уже кем-то реализована. Реализация должна включать в себя описание идеи реализации (каким образом элементы реализуемой структуры хранятся в базовой структуре, какие дополнительные переменные используются) и набор подпрограмм, каждая из которых моделирует некоторое предписание реализуемой структуры при помощи предписаний базовой структуры.
При рассмотрении любой структуры данных необходимо сначала описать ее с логической точки зрения, а затем рассмотреть различные способы ее реализации. В качестве базы реализации в большинстве случаев выступает либо массив, либо динамическая память (т.е. память, в которой можно захватывать участки требуемого размера и освобождать ранее захваченные участки, когда они уже больше не нужны)
Использование очереди в программировании почти соответствует ее роли в обычной жизни. Очередь практически всегда связана с обслуживанием запросов, в тех случаях, когда они не могут быть выполнены мгновенно. Очередь поддерживает также порядок обслуживания запросов. Рассмотрим, к примеру, что происходит, когда человек нажимает клавишу на клавиатуре компьютера. Тем самым человек просит компьютер выполнить некоторое действие. Например, если он просто печатает текст, то действие должно состоять в добавлении к тесту одного символа и может сопровождаться перерисовкой области экрана, прокруткой окна, переформатированием абзаца и т.п.
Любая, даже самая простая, операционная система всегда в той или иной степени многозадачна. Это значит, что в момент нажатия клавиши операционная система может быть занята какой-либо другой работой. Тем не менее, операционная система ни в какой ситуации не имеет права проигноровать нажатие на клавишу. Поэтому происходит прерывание работы компьютера, он запоминает свое состояние и переключается на обработку нажатия на клавишу. Такая обработка должна быть очень короткой, чтобы не нарушить выполнение других задач. Команда, отдаваемая нажатием на клавишу, просто добавляется в конец очереди запросов, ждущих своего выполнения. После этого прерывание заканчивается, компьютер восстанавливает свое состояние и продолжает работу, которая была прервана нажатием на клавишу. Запрос, поставленный в очередь, будет выполнен не сразу, а только когда наступит его черед.
Очередь
Очередью будем называть структуру данных, для которой определены операции добавления и удаления элементов.
Очередь, в которой нет ни одного элемента, называется пустой. В этом случае указатели start и Last указывают на одно и то же место.
Очередь можно реализовать несколькими способами. Простейшим способом реализации служит массив и два указателя. Первый указывает на начало очереди, а второй, соответственно, на ее конец.
Начало очереди — это номер элемента массива, который будет удаляться.
Конец очереди — это номер элемента массива, в который будут заноситься данные.
Реализация очереди на базе массива
Как уже было сказано, программисту массив дан свыше, все остальные структуры данных нужно реализовывать на его основе. Конечно, такая реализация может быть многоэтапной, и не всегда массив выступает в качестве непосредственной базы реализации. В случае очереди наиболее популярны две реализации: непрерывная на базе массива, которую называют также реализацией на базе кольцевого буфера, и ссылочная реализация, или реализация на базе списка.
При непрерывной реализации очереди в качестве базы выступает массив фиксированной длины N, таким образом, очередь ограничена и не может содержать более N элементов. Индексы элементов массива изменяются в пределах от 0 до N - 1. Кроме массива, реализация очереди хранит три простые переменные: индекс начала очереди, индекс конца очереди, число элементов очереди. Элементы очереди содержатся в отрезке массива от индекса начала до индекса конца.
При добавлении нового элемента в конец очереди индекс конца сперва увеличивается на единицу, затем новый элемент записывается в ячейку массива с этим индексом. Аналогично, при извлечении элемента из начала очереди содержимое ячейки массива с индексом начала очереди запоминается в качестве результата операции, затем индекс начала очереди увеличивается на единицу. Как индекс начала очереди, так и индекс конца при работе двигаются слева направо. Что происходит, когда индекс конца очереди достигает конца массива, т.е. N - 1?
Ключевая идея реализации очереди состоит в том, что массив мысленно как бы зацикливается в кольцо. Считается, что за последним элементом массива следует его первый элемент (напомним, что последний элемент имеет индекс N - 1, а первый — индекс 0). При сдвиге индекса конца очереди вправо в случае, когда он указывает на последний элемент массива, он переходит на первый элемент. Таким образом, непрерывный отрезок массива, занимаемый элементами очереди, может переходить через конец массива на его начало.
Если некоторый элемент занесен в очередь раньше других, то он раньше других и подлежит обработке. Данное определение можно сравнить с обычной очередью в магазине — если покупатель пришел первым, то он и обслуживается первым. Другими словами, очередь — эта та структура данных, в которую элемент "заходит" первый и первый же "выходит". Именно поэтому очередь нередко обозначают аббревиатурой FIFO (First In, First Out — первый зашел, первый вышел).
Элементы удаляются из очереди в том же порядке, в котором они были добавлены в очередь.
Пусть у нас есть очередь из трех элементов а, В и С, в которую первым был помещен элемент а, а последним —- элемент С.
Здесь указатель start (начало очереди) определяет место в массиве, откуда очередной элемент будет удаляться, а указатель Last (конец очереди) определяет место в массиве, куда очередной элемент будет добавляться.
Как было сказано выше, сначала обрабатывается элемент, который первый вошел в очередь, в нашем случае это элемент а. Он будет удален из очереди путем смещения указателя start на один элемент вправо.
Теперь добавим некоторый элемент d в очередь. Для этого необходимо записать D в позицию Last, а затем передвинуть указатель Last на один элемент вправо.