- •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.4. Реализация линейного списка с помощью связанного двунаправленного списка
Связанный двунаправленный список состоит из элементов, каждый из которых, кроме первого и последнего, связан с помощью указателей со следующим и предыдущим элементами. В последнем элементе указатель на следующий элемент имеет значения 0, а в первом элементе имеет значения 0 указатель на предыдущий элемент. Для работы с двунаправленным списком удобно использовать два внешних указателя – на первый и последний элементы. По сравнению с однонаправленным связанным списком, в двунаправленном списке эффективнее выполняются операции: прохождение списка в двух направлениях, удаление элемента в заданной позиции, добавление и удаление элемента перед заданным элементом. Двунаправленные списки часто используются для сортировки (методом вставки) и удаления дубликатов.
В языке С++ элемент связанного двунаправленного списка – это структура из трех полей: поля, содержащего значение элемента и двух служебных полей-указателей. Пример объявления типа элемента связанного двунаправленного списка целых чисел:
struct element
{
int info ;
element *prev;
element *next;
};
Пример программы, выполняющей операции над линейным связанным двунапрвленным списком:
#include <iostream.h>
#include <conio.h>
//Добавление элемента x в конец списка
void insertend(element * &begin, element * &end, int x);
//Вывод списка от конца к началу
void print(element* end);
//Удаление элемента в позиции p (при условии, что список не //пуст)
void delp(element * & begin, element * &end, element * p);
void main()
{
element* begin,* end;
int x;
begin= end=0;
cout<<"x ";
cin>>x;
inserend (begin, end, x);
print(end);
cout<<" x ";
cin>>x;
inserend (begin, end, x);
print(end);
delp(begin, end, end); //удаление последнего элемента
print(end);
getch();
}
void insertend(element * &begin, element * &end, int x)
{
element * node;
//Выделение памяти для добавляемого элемента
node=new element;
//Заполнение элемента
node->info=x;
node->next=0;
node->prev= end;
//Включение элемента в список
if(begin ==0)
begin = end =node;
else
{
end ->next=node;
end =node; }
}
void delp(element * &begin, element * &end, element * p)
{ //список не должен быть пустым
if (begin == end) //элемент единственный
{
begin = end =0;
delete p; //освобождение памяти
return;
}
if (p== begin) //первый элемент
{
begin = begin ->next;
begin ->prev=0;
delete p; //освобождение памяти
return;
}
if(p== end) //элемент последний
{
end = end ->prev;
end -> next=0;
delete p;/ освобождение памяти
return;
}
//Элемент посередине
p->next->prev=p->prev;
p->prev->next= p->next; }
delete p; //освобождение памяти
return;
}
void print(element* end)
{
element* node;
if {end==0)
cout<<”list is empty”<<endl;
else
{
node= end;
while (node!=0)
{
cout<<node->info<<' ';
node=node->prev;
}
cout<<endl;
}
}
10.2. Деревья
Во многих задачах обрабатываемые данные имеют нелинейный порядок: элемент данных может иметь несколько последующих или несколько предшествующих элементов. Примерами нелинейных структур данных являются деревья.