- •Программирование и основы алгоритмизации
- •1. Понятие алгоритма
- •1.1. Определение алгоритма
- •1.2. Гост на описание блок-схем
- •1.3. Виды алгоритмов
- •2. Языки программирования
- •2.1. Определение алгоритмического языка
- •2.2. Классификация языков. История развития языков программирования
- •2.3. Выбор языка программирования
- •2.5. Арифметические и логические основы программирования
- •3. Понятие системы программирования
- •3.1. Этапы создания программ
- •3.2. Конструирование программ
- •3.3. Методы, технологии и инструментальные средства производства программных продуктов
- •4.1. Литералы
- •4.2. Встроенные типы данных
- •4.3. Операции
- •Адресные операции
- •Операции преобразования знака
- •Побитовые операции
- •Операция определения размера
- •Операции увеличения и уменьшения значения
- •Операции динамического распределения памяти
- •Операция доступа
- •Аддитивные операции
- •Мультипликативные операции
- •Операции сдвига
- •Поразрядные операции
- •Операции сравнения
- •Логические бинарные операции
- •Операция присваивания
- •Специальные формы операций присваивания
- •Операции выбора компонентов структурированного объекта
- •Операции обращения к компонентам класса
- •Операция управления процессом вычисления значений
- •Операция вызова функции
- •Операция явного преобразования типа
- •Операция индексации
- •4.5. Агрегатные типы данных
- •4.5.1. Массивы
- •4.5.2. Структуры
- •4.5.3. Поля битов
- •4.5.4. Объединения Используются для хранения значений различных типов в одной и той же области памяти, но не одновременно.
- •4.5.5. Перечисления
- •4.5.6. Переименование типов
- •Typedef имя ранее определенного типа имя нового типа1
- •Объявление typedef применяется для создания удобных распознаваемых имен часто встречающихся и для вложенных типов, а также, чтобы сделать программы переносимыми для различных целых типов.
- •4.6. Обработка символьных и строковых переменных
- •4.7. Указатели
- •4.7.1. Инициализация указателей
- •4.7.2. Операции с указателями
- •4.8. Пользовательские процедуры и функции
- •4.8.1. Перегрузка функций
- •4.8.2. Перегрузка операций
- •4.8.3. Шаблоны функций
- •4.8.4. Возврат из функции нескольких значений
- •4.9. Файлы
- •4.10. Директивы препроцессора
- •Библиографический список
4.5. Агрегатные типы данных
Кроме рассмотренных ранее стандартных типов данных язык С++ позволяет создавать дополнительные агрегатные типы данных:
– массивы;
– структуры (structure);
– объединения (union);
– поля битов (bit fields);
– перечисления или перечислимый тип (enumeration);
– с помощью оператора typedef .
4.5.1. Массивы
Массив – это упорядоченная последовательность данных одного типа, имеющих одно имя. Массив описывается следующим образом:
<тип> <имя массива> [n1] [n2]…
где n1, n2 – размер массива по данному измерению.
Элемент массива представляет собой индексированную переменную , индекс которой указывается в квадратных скобках. Индекс может быть целой константой, целой переменной или выражением целого типа. Все массивы индексируются с нуля.
Массивы подобно переменным могут быть инициализированы начальными значениями, например.
float a[3]={1.2, 3.4, -0.1};
где a[0]=1.2, a[1]=3.4, a[2]=-0.1.
Имя массива является константой указателем на адрес первого элемента массива. Начальный адрес массива определяется компилятором в момент описания массива и не может быть переопределен.
Наиболее серьезная и распространенная ошибка при работе с массивами – выход за границу массива, т.е. когда предпринимается попытка записать или прочитать значение по адресу памяти, который не был описан в программе.
При работе с массивами выделяют следующие типовые операции:
1. Заполнение массива возможно либо с помощью генератора случайных чисел (random()), либо с клавиатуры, либо по определенному правилу.
Пример.
for (i=0; i<n; i++)
for (j=0; j<n; j++)
cin>> a [i][j];
В квадратной матрице выделяют главную и побочную диагонали, относительно которых элементы могут находиться выше или ниже (рис.2).
Рис. 2. Принятое деление матрицы на четверти
Условия нахождения элементов в каждой из частей матрицы следующие:
I: (i<j) && (i+j<n-1)
II: (i<j) && (i+j>n-1)
III: (i>j) && (i+j>n-1)
IV: (i>j) && (i+j<n-1)
на главной диагонали: i = = j
на побочной диагонали: i+j = = n-1
где i – номер строки, j – номер столбца, в которых находится элемент матрицы, n – размерность квадратной матрицы.
2. Вычисление суммы, произведения, среднего арифметического, среднего геометрического, количества элементов, удовлетворяющих некоторому условию.
Пример. Вычислить сумму положительных элементов матрицы и количество отрицательных элементов.
for (i=0; i<n; i++)
for (j=0; j<n; j++)
{if a[i][j]>0 s+=a[i][j];
else k++;
}
3. Сортировка массива
Можно выделить пять типов алгоритмов сортировки:
обменом – выполняются проходы по файлу с обменом местами элементов до тех пор, пока файл не будет окончательно отсортирован;
вставками – отдельно анализируется каждый конкретный элемент, который затем помещается на надлежащее ему место среди других, уже отсортированных элементов;
выбором – сначала отыскивается наименьший элемент массива, затем он меняется местами с элементом, стоящим первым в сортируемом массиве, и т.д.;
слиянием – сортируемый файл, расположенный во внешней памяти, разбивается на части, которые могут быть считаны в память, отсортированы каким-либо методом и записаны в отдельные временные файлы. Затем отсортированные временные файлы сливаются попарно с сохранением порядка сортировки. И так до тех пор, пока все временные файлы не будут объединены в один отсортированный файл;
деревом – сортируемые элементы добавляются в бинарное дерево. Отсортированный массив формируется путем концевого обхода построенного дерева.
Основной характеристикой алгоритма сортировки является время, затраченное на его выполнение. Так, для массива из N элементов:
сортировка выбором производит в среднем N^2 / 2 операций сравнения и операций обмена;
сортировка вставками – в среднем N^2 / 4 сравнений и N^2 / 4 операций полуобмена (перемещений) и в два раза больше в наихудшем случае;
сортировка обменом (метод пузырька) – N^2 / 2 операций сравнения и N^2 / 2 обменов как в среднем, так и наихудшем случае;
сортировка деревом – N * log2 (N) операций сравнения и N операций вставки.
Пример. Идея метода сортировки выбором состоит в том, чтобы создавать отсортированную последовательность путем присоединения к ней одного элемента за другим в правильном порядке.
Шаги алгоритма:
находим минимальное значение в текущем списке;
производим обмен этого значения со значением на первой позиции;
сортируем хвост списка, исключив из рассмотрения уже отсортированный первый элемент.
Будем строить выходную последовательность, начиная с левого конца массива. Алгоритм состоит из n последовательных шагов, начиная с нулевого и заканчивая (n-1)-м.
На i-м шаге выбираем наименьший из элементов x[i] ... x[n] и меняем его местами с x[i]. Последовательность шагов при n=5 изображена на рис. 2.
Рис. 2. Сортировка выбором
Вне зависимости от номера текущего шага i, последовательность x[0]...x[i] (выделена курсивом) является упорядоченной. Таким образом, на (n-1)-м шаге вся последовательность, кроме x[n], оказывается отсортированной, а x[n] стоит на последнем месте по праву: все меньшие элементы уже ушли влево.
Пример программной реализации.
for (i = 0; i < n-1; i++) {
min = i;
for (j = i+1; j < n; j++) {
if (x[min] > x[j]) { // сортировка по убыванию
min = j;
}
}
temp = x[i];
x[i] = x[min];
x[min] = temp;
}
4. Вставка и удаление элементов массива
Удаление одного элемента из массива происходит по следующей схеме:
- указывается или ищется порядковый номер элемента, который необходимо удалить из массива;
- все элементы, стоящие за удаляемым элементом, сдвигаются на одну позицию влево;
- количество элементов уменьшается на единицу.
for (i=0; i<n; i++) // n – номер удаляемого элемента
a[j]=a[j+1];
k-=1; // количество элементов