Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты на зачет.docx
Скачиваний:
51
Добавлен:
01.06.2015
Размер:
554.66 Кб
Скачать
    1. Элементарные Структуры Данных

Для многих задач выбор подходящей структуры данных является самым главным решением, принимаемым в процессе их реализации. Для одних и тех же данных, разные структуры требуют большие или меньшие объемы памяти, а также предполагают различную эффективность тех или иных операций. Таким образом, выборы алгоритмов и структур данных очень тесно связаны друг с другом.

Обычно, мы будем иметь дело с массивами, связанными списками, стеками, очередями и другими простейшими типами данных. Это классические, широко распространенные, структуры данных: они, вместе с деревьями, составляют базис практически для всех алгоритмов, с которыми мы будем иметь дело. Сейчас мы сосредоточим внимание на основных способах их представления и фундаментальных методах, манипулирующих этими структурами, разберем некоторые примеры их использования, и обсудим связанные с этим вопросы такие, как выделение памяти.

      1. Массивы

Возможно, самым основным типом данных являются массивы, которые определены в Паскале и большинстве других языков программирования. Массив – это фиксированное количество элементов данных, которые хранятся в нем последовательно и доступны по индексу. Кi-му элементу массиваa, мы обращаемся как кa[i]. На совести программиста остается обязанность побеспокоиться о том, чтобы перед первым чтением любого элемента массива в нем находилось что-либо имеющее смысл. Процесс предварительного предания переменным «значащего» значения называетсяинициализацией. Пренебрежение инициализацией является наиболее распространенной ошибкой при написании программ.

В нижеприведенной программе, которая печатает все простые числа меньшие 1000, дан простейший пример использования массивов. Метод, использованный в этой программе, называется «решето Эратосфена» и был впервые применен уже 300 лет до рождества Христова:

const N=1000;var a :array[1..N]of boolean; i, j : integer;begin fori := 1toNdoa[i] := true;fori := 2toNdiv 2doforj:= 2toNdiv idoa[i*j] :=false;fori := 1toNdoifa[i]thenwrite(i:4);end;

Программа использует массив, состоящий из элементов самого простого типа, логического. Цель программы – присвоить элементу массива a[i] значение true,если i простое иfalse в противном случае. Это достигается посредством того, что для любогоi, мы устанавливаем элементы массива с индексами кратнымиiв значениеfalseпотому, что любое число кратное какому либо целому не может быть простым. Затем программа еще раз проходит по массиву, распечатывая простые числа. (Можно сделать эту программу несколько более эффективной, добавив проверкуifa[i] thenперед цикломforпоjтак, как еслиiне простое, то все элементы массива соответствующие его произведению на некоторое число уде помечены.) Заметьте, что массив был изначально проинициализирован, чтобы показать, что ни одно из чисел не известно как «непростое»: алгоритм устанавливает вfalseлишь те элементы массиваa, индексы которых были опознаны как непростые числа.

Решето Эратосфена является типичным алгоритмом, использующим факт, что любой элемент массива можно эффективно использовать. Кроме того, алгоритм использует элементы массива последовательно, один за другим. Во многих задачах, последовательный порядок доступа очень важен; в некоторых других задачах последовательный доступ используется потому, что он столь же хорош, как и другие. Но самое главное свойство массивов состоит в том, что если индекс известен, то обращение клюбомуэлементу массива производится за постоянное время, не зависящее от индекса.

Размер массива должен быть известен заранее. В Паскале, он должен быть известен уже во время компиляции. Чтобы запускать вышеприведенную программу при разных значениях N, необходимо сначала изменитьN, затем снова откомпилировать ее и запустить. В некоторых программных оболочках есть возможность объявлять размеры массива во время выполнения программы (чтобы, например, дать пользователю ввести значениеN, а затем вывести все простые числа меньшие либо равныеNбез дополнительных затрат памяти на хранение максимально большого массива), но и в этом случае размер массива постоянен и должен быть известен до того, как он первый раз использован.

Массивы относят к одним из фундаментальных структур данных еще и потому, что существует прямое соответствие между массивами и памятью на практически всех типах компьютеров. Для получения содержимого из памяти компьютера мы должны знать адрес. Таким образом, можно думать о памяти компьютера как о массивы, с адресами соответствующими индексам. Большинство языков программирования преобразуют программы в высокоэффективные программы в машинных кодах, которые используют память напрямую.

Другой знакомый нам всем способ структурирования информации – использование двухмерных таблиц чисел организованных в столбцы и колонки. Рассмотрим, например, таблицу, содержащую оценки студентов за домашние задания. На компьютере такая таблица называется двухмерным массивом. У него два индекса, один для столбца, другой для строки. Алгоритмы, определенные на таких структурах очень просты: например, чтобы подсчитать средний бал, мы суммируем все числа в этом массиве и делим на количество элементов в этом массиве, а чтобы подсчитать средний бал одного студента, мы суммируем все его оценки и делим на количество заданий. Двухмерные массивы широко используются в задачах такого рода. На самом же деле, на компьютере довольно удобно использовать и более чем двухмерные массивы: преподаватель может использовать третье измерение для обозначения года, за который эта таблица успеваемости.

Массивы также являются прямым прообразом векторов. Аналогично, двухмерные массивы соответствуют матрицам.

Многомерные массивы хранятся в памяти как одномерные. Так, двумерный массив располагается в памяти следующим образом: сначала идет первая строка (как одномерный массив), затем вторая, третья и так далее.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]