- •1.Связное представление данных в памяти
- •2.Односвязный список: структура, машинное представление , операции.
- •3. Двусвязный список: структура, машинное представление , операции.
- •Удаление элемента из двунаправленного списка
- •Поиск элемента в двунаправленном списке
- •Проверка пустоты двунаправленного списка
- •Удаление двунаправленного списка
- •4. Кольцевой список: структура, машинное представление , операции.
- •5.Очередь: понятие, структура, операции
- •10.Открытое хеширование
- •11.Закрытое хеширование
- •13.Понятие дерева, бинарного дерева, сбалансированного дерева.
- •14.Алгоритм горизонтального обхода дерева.
- •15.Алгоритм вертикального обхода дерева.
- •16.Обход графа в ширину.
- •17.Алгоритм обода графа в глубину
- •18.Алгоритм Флойда-Уоршалла
- •19.Алгоритм Дейкстры.
- •20. Алгоритм Белламана-Форда
- •21.Алгоритмы поиска и сортировки деревьями: метод ветвей и границ.
- •22.Алгоритмы поиска и сортировки деревьями: перебор с возвратом.
- •2.1.1. Общая схема
14.Алгоритм горизонтального обхода дерева.
Рекурсия удобна при обходе деревьев, однако ей нельзя осуществить горизонтальный обход дерева. В этом случае, а так же при обеспокоенности перегрузкой программного стека, следует применять итерационный подход.
При обходе в ширину узлы посещаются уровень за уровнем(N-й уровень дерева - множество узлов с высотой N). Каждый уровень обходится слева направо. Для дерева изображенного на рисунке 1.2 обход в ширину представляет последовательность вершин:
A- B –C – D – E – F – K - G
И графически (рисунок 2.4):
Заметим, что перечисление узлов происходит в порядке удаления от корня, что делает поиск в ширину удобным, например, для поиска узла дерева со значением k, наиболее близкого к корню, и т.д.
Для реализации используется структура queue - очередь с методами
enqueue - поставить в очередь
dequeue - взять из очереди
empty - возвращает TRUE, если очередь пуста, иначе – FALSE.
И часть программного кода для данного обхода будет соответственно иметь вид:
/*ОБХОД В ШИРИНУ*/
q.enqueue(root); // корень в очередь
while (! q.empty) {
der = q.dequeue();
visit der; // посетить der
if (! der.left.empty) // der.left - левое поддерево
q.enqueue(der.left);
if (! der.right.empty) // der.right - правое поддерево
q.enqueue(der.right);}
15.Алгоритм вертикального обхода дерева.
2.1. Нисходящий обход.
Как было описано ранее, нисходящий или прямой обход дерева выглядит следующим образом: корень - левое поддерево - правое поддерево.
Для дерева, изображённого на рисунке 1.2 нисходящий обход представляет собой последовательность вершин:
A-B-D-G-E-C-F-K
Наглядно это представлено на рисунке 2.1:
Программный код для прямого обхода бинарного дерева будет иметь вид:
Пример 2.1.1
/*ОБХОД В ПЯМОМ ПОРЯДКЕ (НИСХОДЯЩИЙ ОБХОД)*/
void pram_ob (derevo *&svob)
{
if (NULL==svob) return; //Если дерева нет, выходим
printf("%d\n",svob->x); //Посетили узел
pram_ob (svob->left); //Обошли левое поддерево
pram_ob (svob->rite); //Обошли правое поддерево
}
Помимо рекурсивного обхода, существует инерационный прямой обход с использованием стека. Его программный код будет иметь вид:
void pram_iter_ob(derevo *current, int l)
{
int flag=0;
while(flag==0)
{
while(current!=NULL)
{
l++;
Push(current, l);
for( int i=0; i<l; i++)
cout << "\t";
cout << current->info << endl;
current=current->left;
}
if(stack==NULL)
flag=1;
else
{
l=Pop(¤t);
current=current->right;
} } }
2.2. Восходящий обход.
Восходящий обход осуществляется по схеме: левое поддерево - правое поддерево – корень. Для дерева, изображённого на рисунке 1.2 нисходящий обход представляет собой последовательность вершин:
G-E-D-B-F-K-C-A
Графически это выглядит так (рисунок 2.2):
2.3. Смешанный обход
Смешанный обход осуществляется по схеме: левое поддерево – корень – правое поддерево. Для дерева изображенного на рисунке 1.2 смешанный обход представляет последовательность вершин:
G – D – B – E – A – F – C – K
Выглядит это следующим образом (рисунок 2.3):
