![](/user_photo/2706_HbeT2.jpg)
- •1.1. Элементы языка программирования
- •Основные правила записи программы:
- •1.2. Алфавит языка
- •1.3. Лексемы
- •1.4. Концепция данных
- •2.2. Операции
- •2.2.1. Арифметические операции
- •2.2.2. Операции присваивания
- •2.2.3. Операции отношения
- •2.2.4. Логические операции
- •2.2.5. Поразрядные операции
- •2.2.6. Вычисление выражений
- •3. Структурное программирование
- •3.1. Общая характеристика операторов
- •3.2. Оператор-выражение
- •3.3. Условный оператор
- •3.4. Составной оператор
- •3.5. Операторы для программирования циклов
- •3.5.1. Оператор цикла for
- •3.5.2. Оператор цикла while
- •3.5.3. Оператор цикла do while
- •3.5.4. Оператор break
- •3.5.5. Оператор continue
- •3.6. Оператор goto
- •3.7. Пустой оператор
- •3.8. Оператор switch
- •3.9. Оператор return
- •4. Массивы
- •4.1. Объявление массива
- •4.2. Обращение к элементам массива
- •4.3. Типовые алгоритмы работы с массивами
- •4.4. Многомерные массивы
- •5. Строки
- •5.1. Объявление строки
- •5.2. Посимвольная обработка строк
- •5.3. Ввод строк
- •5.4. Библиотечные функции для работы с текстом
- •6. Указатели
- •6.1. Объявление указателей
- •6.2. Операции над указателями
- •6.3. Связь между указателями и массивами
- •6.4. Функция strtok для выделения лексем из текста
- •6.5. Динамические массивы
- •7. Структуры и объединения
- •7.1. Объявление структуры
- •Компонент структуры может быть любого типа, кроме типа объявляемой структуры.
- •7.2. Операции над структурами
- •7.3. Объявление объединения
- •8. Модульное программирование
- •8.1. Нисходящее проектирование и программирование
- •8.2. Определение и вызов функции
- •8.3. Место определения функции в программе
- •8.4. Обмен данными между функциями
- •8.4.1. Использование глобальных переменных
- •8.4.2. Использование аппарата формальных и фактических параметров
- •8.4.3. Передача массивов в функцию
- •8.5. Перегрузка функции
- •8.6. Шаблон функции
- •8.7. Рекурсивные функции
- •8.8. Функции с параметрами по умолчанию
- •8.9. Передача в функцию другой функции
- •9. Работа с файлами
- •9.1. Текстовые и двоичные файлы
- •9.2. Объявление файловых переменных
- •9.3. Чтение текстового файла
- •9.4. Создание текстового файла
- •9.5. Изменение данных в текстовом файле
- •9.6. Вывод в двоичный файл
- •9.7. Чтение данных из двоичного файла
- •9.8. Изменение данных двоичного файла
- •9.9. Организация файла с произвольным доступом
- •10. Данные с динамической структурой
- •10.1. Линейный список
- •10.1.1. Специальные типы линейных списков
- •10.1.2. Реализация линейного списка с помощью массива
- •10.1.3. Реализация линейного списка с помощью связанного однонаправленного списка
- •10.1.4. Реализация линейного списка с помощью связанного двунаправленного списка
- •10.2. Деревья
- •10.2.1. Основная терминология
- •10.2.2. Реализация двоичных деревьев поиска Для реализации дерева поиска используются массивы и связанные указателями элементы [3, 4].
- •10.2.3. Сбалансированные деревья
- •Основные достоинства в-дерева:
- •10.3. Графы
- •10.3.1. Определения
- •10.3.2. Реализация графа с помощью списков смежности
- •10.3.3. Реализация графа с помощью матрицы смежности
- •10.3.4. Поиск кратчайших путей. Алгоритм Дейкстры
- •10.3.5. Матрица достижимости. Алгоритм Уоршалла
10.1.1. Специальные типы линейных списков
В программировании часто используют специальные типы линейные списков, которые имеют специальные названия.
Стек – это линейный список, в котором все включения, исключения и доступ выполняются только с одного конца списка, называемом вершиной стека. Дисциплина обслуживания стека обозначается аббревиатурой LIFO (last-in-first-out: последний пришел – первым ушел). Над стеком выполняют операции:
возвращение элемента из вершины стека;
удаление элемента из вершины стека;
вставка элемента в вершину стека;
очистка стека;
проверка стека на пустоту.
Стек в программировании часто используется для временного хранение данных, например, стек программы используется для хранения локальных переменных вызываемых подпрограмм. По мере выполнения подпрограмм стек программы освобождается.
Очередь – это линейный список, в котором все включения элементов выполняются с одного конца списка, называемого концом очереди, а исключения элементов и доступ к элементам - с другого конца списка, называемого началом очереди. Дисциплина обслуживания очереди обозначается аббревиатурой FIFO (fist-in-first-out: первый пришел – первый ушел). Над очередью выполняют операции:
возвращение элемента из начала очереди;
удаление элемента из начала очереди;
вставка элемента в конец очереди;
очистка очереди;
проверка очереди на пустоту.
Примером очереди является очередь заданий на печать к одному принтеру при использовании компьютеров локальной сети.
Очередь с приоритетами – это линейный список, в котором все элементы имеют приоритет. Включения в очередь с приоритетами выполняются с одного конца. Первым обслуживается (исключается и просматривается) элемент с наибольшим приоритетом. Если несколько элементов имеют равный приоритет, то первым обслуживается элемент, который был включен в очередь раньше. Примером очереди с приоритетами является очередь заданий на печать к одному принтеру, для заданий, имеющих разный приоритет.
Дек – это линейный список, в котором операции включения, исключения и доступа выполняются только на концах списка. Существуют два специальных типа дека: дек с ограниченным входом и дек с ограниченным выходом. В деке с ограниченным входом включение элементов выполняется только с одного конца, а исключение элементов и доступ к элементам – с двух концов. В деке с ограниченным выходом исключение элементов и доступ к ним выполняется только с одного конца дека, а включение элементов – с двух концов.
10.1.2. Реализация линейного списка с помощью массива
При реализации списка с помощью массива элементы списка располагаются в смежных участках памяти. Такое представление списка позволяет:
легко просматривать весь список;
быстро находить элемент списка по его положению (индексу);
эффективно выполнять операции добавления/ удаления в конец списка;
использовать алгоритмы быстрого поиска элемента для упорядоченного списка.
Недостатки реализации:
большие временные затраты на выполнение операций включения и исключения элементов в середину или начало списка, так как эти операции требуют перемещения всех последующих элементов на одну позицию к концу (началу) массива;
память под массив должна выделяться с запасом, чтобы исключить переполнение массива;
выделенный объем памяти сохраняется за списком даже при удалении части элементов из списка (для динамического массива можно изменить размер памяти под список во время выполнения программы, но операция изменения размера памяти требует выполнения копирования элементов массива в новый массив и приводит к большим временным затратам).
Пример программы, выполняющей операции: включение в конец списка, исключение из начала списка, поиск номера элемента с заданным значением. Для реализации списка используется статический массив целых чисел.
#include <iostream.h>
#include <conio.h.
сonst int size=100; //максимальная длина списка
//Функция включает в конец списка из n элементов число х, при
//переполнении списка ok=false
void insert (int &n, int a[], int x, bool &ok);
//Функция исключает последний элемент из списка и
//возвращает его значение х, при пустом списке ok=false
void del (int &n, int a[], int &x, bool &ok);
//Функция находит номер первого элемента со значением х и
// возвращает его, при отсутствии элемента возвращает -1
int search(int n, int a[], int x,);
void main()
{
int a[size]; //массив для хранения списка
int n; //текущий размер списка
int x, m; // значение элемента списка и его номер
bool ok; //признак выполнения операции
cout<<”n? “; cin>>n;
cout<<”a? “;
//Ввод списка в массив
for (int i=0; i<=n-1; i++)
cin>>a[i];
cout<<”x? “; cin>>x;
//Поиск позиции вхождения х в список
m=search(n,a,x);
if (m==-1)
cout<<”No”<<endl;
else
<<”m=”<<m<<endl;
cout<<”x? “; cin>>x;
//Включение элемента со значением х в список
insert(n,a,x,ok);
if (!ok)
cout<<”Error”<<endl;
//Исключение последнего элементаиз списка
del(n,a,x,ok);
cout<<”x=”<<x;
getch();
}
void insert (int &n, int a[], int x, bool &ok)
{
if (n==size)
ok=false;
else
{
a[n]=x;
n++;
ok=true;
}
}
void del (int &n, int a[], int &x, bool &ok)
{
if (n==0)
ok=false;
else
{
x=a[n];
n--;
ok=true;
}
}
int search(int n, int a[], int x,)
{
for (int i=0; i<=n-1; i++)
if (a[i]==x)
return i;
return -1;
}