Разделы презентаций


Деревья: теория и практика использования

Содержание

Шаблон класса бинарного дереваtemplate class Tree { struct Node { T item; Node *left; Node *right; Node( const T& item, Node *left

Слайды и текст этой презентации

Слайд 1Деревья: теория и практика использования

Деревья: теория и практика использования

Слайд 2Шаблон класса бинарного дерева
template
class Tree {
struct Node

{
T item;
Node *left;
Node *right;

Node( const T& item,
Node *left = 0, Node *right = 0 ) {
Node::item = item;
Node::left = left;
Node::right = right;
};
public:
Node *root;

Tree() { root = 0; }
~Tree();
};
Шаблон класса бинарного дереваtemplate class Tree { struct Node {  T item;  Node *left;

Слайд 3Дерево общего вида как бинарное
template
class Tree {
public:
struct

Node {
T item;
Node *son;
Node

*brother;
Node( const T& item,
Node *son = 0, Node *brother = 0 ) {
Node::item = item;
Node::son = son;
Node::brother = brother;
};
private:
Node *root;
public:
Tree() { root = 0; }
~Tree();
};
Дерево общего вида как бинарноеtemplate class Tree {public: struct Node {  T item;  Node *son;

Слайд 4Высота бинарного дерева

Высота бинарного дерева

Слайд 5Формальное определение высоты дерева
Упражнение

Реализуйте рекурсивный алгоритм определения высоты дерева

Формальное определение высоты дереваУпражнениеРеализуйте рекурсивный алгоритм определения высоты дерева

Слайд 6Определение высоты дерева
template
int Tree::height() const {
if( root

== 0 ) return 0;
return root->height();
}

template
int Tree::Node::height()

const {
int max = 0;
for( Node *cur = son;
cur != 0;
cur = cur->brother ) {
int curHeight = cur->height();
if( curHeight > max ) max = curHeight;
}
return max+1;
};
Определение высоты дереваtemplate int Tree::height() const { if( root == 0 ) return 0; return root->height();}template int

Слайд 7Важные для практики частные случаи бинарных деревьев
Во многих случаях информация

о взаимном расположении узлов может определяться способом размещения древовидной структуры

в памяти
Удается обойтись без явных указателей на дочерние и родительские узлы
«Упакованное» бинарное дерево

Важные для практики частные случаи бинарных деревьевВо многих случаях информация о взаимном расположении узлов может определяться способом

Слайд 8Полностью сбалансированное дерево

Полностью сбалансированное дерево

Слайд 9Хранение сбалансированного дерева в виде одномерного массива
Пусть r – номер

узла
Тогда номер родителя: r/2
Номер корня левого поддерева: 2r
Номер корня правого

поддерева: 2r+1

Индекс элемента в массиве: r-1
Дерево можно «упаковать» в одномерный массив и операции над узлами свести к операциям над индексами элементов массива

Хранение сбалансированного дерева в виде одномерного массиваПусть r – номер узлаТогда номер родителя: r/2Номер корня левого поддерева:

Слайд 10Просмотр от самого левого узла к самому правому
// Обработать бинарное

дерево из n узлов с
// корнем в узле noRoot
void

ProcessTree( int noRoot )
{
if( noRoot > n ) return; // выход из рекурсии
// Обработать левое поддерево
ProcessTree( noRoot*2 );
// Обработать корень дерева
// ...
// Обработать правое поддерево
ProcessTree( noRoot*2 + 1 );
}
Просмотр от самого левого узла к самому правому// Обработать бинарное дерево из n узлов с // корнем

Слайд 11Сортировка с использованием бинарного дерева (heap sort)
Другие названия: «сортировка сложным

выбором», «пирамидальная сортировка»
Алгоритм также использует обработку «упакованного» бинарного дерева
В основе

– понятие пирамиды:
Для любого узла r, имеющего одного потомка, справедливо:
Для любого узла r, имеющего двух потомков,
справедливо:

Сортировка с использованием бинарного дерева (heap sort)Другие названия: «сортировка сложным выбором», «пирамидальная сортировка»Алгоритм также использует обработку «упакованного»

Слайд 12Пирамидальная сортировка: свойства пирамиды
Таким образом, корневая вершина поддерева, являющегося пирамидой,

содержит, соответствует наибольшему значению ключа в этом поддереве
Любой лист дерева

является пирамидой по определению

Пирамидальная сортировка: свойства пирамидыТаким образом, корневая вершина поддерева, являющегося пирамидой, содержит, соответствует наибольшему значению ключа в этом

Слайд 13Пирамидальная сортировка: описание процесса сортировки
for( last = n; // Номер

последнего узла

// в начале равен n
last > 0; // Продолжаем, пока не рассмотрели
// все узлы
last-- )
{
// Поменять местами узлы с номерами
// 1 (корневой) и last
// ...
// Восстановить пирамиду из дерева с узлами
// от 1 до last-1 (просеивание)
// ...
}
Пирамидальная сортировка: описание процесса сортировкиfor( last = n; // Номер последнего узла

Слайд 14Пирамидальная сортировка: восстановление пирамиды (1)

Пирамидальная сортировка: восстановление пирамиды (1)

Слайд 15Пирамидальная сортировка: восстановление пирамиды (2)

Пирамидальная сортировка: восстановление пирамиды (2)

Слайд 16Пирамидальная сортировка: восстановление пирамиды (3)

Пирамидальная сортировка: восстановление пирамиды (3)

Слайд 17Пирамидальная сортировка: восстановление пирамиды (4)

Пирамидальная сортировка: восстановление пирамиды (4)

Слайд 18Пирамидальная сортировка: функция просеивания «дыр»
template
void Sift( T *a,

int root, int last )
{
int hole = root;



T x = a[ hole-1 ];
for( ; ; )
{
int left = 2*hole;
int right = left + 1;
int pretender; // Номер претендента
if( left > last ) break; // Если лист –
// просеивание
// закончено
Пирамидальная сортировка: функция просеивания «дыр»template void Sift( T *a, int root, int last ){  int hole

Слайд 19Пирамидальная сортировка: функция просеивания «дыр»
// Теперь

нужно выбрать
// претендента на заполнение

«дыры»
if( left == last ) pretender = left;
else
{
if( a[ left-1 ] < a[ right-1 ] )
pretender = right;
else pretender = left;
}
Пирамидальная сортировка: функция просеивания «дыр»    // Теперь нужно выбрать     //

Слайд 20Пирамидальная сортировка: функция просеивания «дыр»
// Если

претендент не лучше x –
//

просеивание закончено
if( a[ pretender-1 ] < x ) break;
if( a[ pretender-1 ] == x ) break;

// Иначе: претендент заполняет «дыру»,
// при этом образуется новая «дыра»
a[ hole-1 ] = a[ pretender-1 ];
hole = pretender;
}
// Рано или поздно x «возвращается»
// в дерево
a[ hole-1 ] = x;
} // конец функции Sift
Пирамидальная сортировка: функция просеивания «дыр»    // Если претендент не лучше x –

Слайд 21Что нужно для сортировки всей последовательности?
Подготовить пирамиду в самом начале

(это достигается за n/2 просеиваний)
Осуществить цикл из n-1 просеиваний, на

каждой итерации которого элемент с наибольшим значением ключа занимает свое окончательное место

Что нужно для сортировки всей последовательности?Подготовить пирамиду в самом начале (это достигается за n/2 просеиваний)Осуществить цикл из

Слайд 22Иллюстрация первоначальной подготовки пирамиды (1)

Иллюстрация первоначальной подготовки пирамиды (1)

Слайд 23Иллюстрация первоначальной подготовки пирамиды (2)

Иллюстрация первоначальной подготовки пирамиды (2)

Слайд 24Иллюстрация первоначальной подготовки пирамиды (3)

Иллюстрация первоначальной подготовки пирамиды (3)

Слайд 25Иллюстрация первоначальной подготовки пирамиды (4)

Иллюстрация первоначальной подготовки пирамиды (4)

Слайд 26Иллюстрация первоначальной подготовки пирамиды (5)

Иллюстрация первоначальной подготовки пирамиды (5)

Слайд 27Иллюстрация первоначальной подготовки пирамиды (6)

Иллюстрация первоначальной подготовки пирамиды (6)

Слайд 28Иллюстрация первоначальной подготовки пирамиды (7)

Иллюстрация первоначальной подготовки пирамиды (7)

Слайд 29Иллюстрация первоначальной подготовки пирамиды (8)

Иллюстрация первоначальной подготовки пирамиды (8)

Слайд 30Пирамидальная сортировка: реализация
template
void HeapSort( T *a, int n

) {
int root, last;
// Первоначальная подготовка

пирамиды
for( root = n/2; root > 0; root-- )
Sift( a, root, n );
// Цикл сортировки
for( last = n; last > 1; last-- ) {
T copy = a[ 0 ];
a[ 0 ] = a[ last-1 ];
a[ last-1 ] = copy;
Sift( a, 1, last-1 );
}
}
Пирамидальная сортировка: реализацияtemplate void HeapSort( T *a, int n ) {  int root, last;  //

Слайд 31Обход дерева
Левосторонний инфиксный обход
внутренний итератор
рекурсивная процедура
Нисходящий обход в глубину
внутренний итератор
стек,

хранящий информацию о непройденных поддеревьях
Нисходящий обход в ширину
внешний итератор
очередь
Восходящий обход

от корней к вершине
внешний итератор
стек


Обход дереваЛевосторонний инфиксный обходвнутренний итераторрекурсивная процедураНисходящий обход в глубинувнутренний итераторстек, хранящий информацию о непройденных поддеревьяхНисходящий обход в

Слайд 32Для простоты используем:
template
class Tree {
struct Node {

T item;
Node *left;
Node *right;

Node( const T& item,
Node *left = 0, Node *right = 0 ) {
Node::item = item;
Node::left = left;
Node::right = right;
};
public:
Node *root;

Tree() { root = 0; }
~Tree();
};
Для простоты используем:template class Tree { struct Node {  T item;  Node *left;  Node

Слайд 33template
class Actor {
public:
virtual void action( T& node)

= 0;
};
template
void Tree::traverseInfixLeft(Actor& a) {
recursiveInfixLeft( root, a

);
}

template
void Tree::recursiveInfixLeft( Node *node,
Actor& a ) {
if( node ) {
recursiveInfixLeft( node->left, a );
a.action( node->item );
recursiveInfixLeft( node->right, a );
}
}

// Левосторонний инфиксный обход

template class Actor {public: virtual void action( T& node) = 0;};template void Tree::traverseInfixLeft(Actor& a) { recursiveInfixLeft( root,

Слайд 34template
void Tree::traverseUpDown( Actor& a ) {
stack st;

Node *cur = root;
for( ; ; ) {

a.action( cur->item );
if( cur->right != 0 && cur->left != 0 ) {
st.push( cur->right );
cur = cur->left;
} else if( cur->left != 0 ) {
cur = cur->left;
} else if( cur->right != 0 ) {
cur = cur->right;
} else {
if( st.empty() ) break;
cur = st.top();
st.pop();
}
}
}

// Обход в глубину с использованием стека

template void Tree::traverseUpDown( Actor& a ) { stack st; Node *cur = root; for( ; ; )

Слайд 35template
void Tree::traverseInfixStack( Actor& a ) {
stack st;

Node *cur = root;
while( !st.empty() ) {
st.push(

cur );
if( cur->left != 0 ) {
cur = cur->left;
}
else do {
if( st.empty() ) break;
cur = st.top();
st.pop();
a.action( cur->item );
cur = cur->right;
} while( cur == 0 );
}
}

// Преобразование traverseInfixLeft с
// использованием стека

template void Tree::traverseInfixStack( Actor& a ) { stack st; Node *cur = root; while( !st.empty() ) {

Слайд 36Коды Хаффмана
Сообщения состоят из символов
Вероятность появления символов – различная
Как закодировать

символы, чтобы уменьшить длину сообщения?
«Регулярный» код: просто, но не оптимально
Идея

– использовать код переменной длины
Префиксное свойство

Коды ХаффманаСообщения состоят из символовВероятность появления символов – различнаяКак закодировать символы, чтобы уменьшить длину сообщения?«Регулярный» код: просто,

Слайд 37Пример (Ахо, Хопкрофт, Ульман)
Код 1: 001010011 => BCD
Код 2: 1101001

=> BCD
Задача: минимизировать код

Пример (Ахо, Хопкрофт, Ульман)Код 1: 001010011 => BCDКод 2: 1101001 => BCDЗадача: минимизировать код

Слайд 38Алгоритм Хаффмана
Определение структуры дерева, представляющего используемый код
Построение леса из деревьев

путем объединения листьев, соответствующих кодам с наименьшими вероятностями

Алгоритм ХаффманаОпределение структуры дерева, представляющего используемый кодПостроение леса из деревьев путем объединения листьев, соответствующих кодам с наименьшими

Слайд 41C
D
A
0.35

CDA0.35

Слайд 42C
D
A
B
E
0.35
0.65

CDABE0.350.65

Слайд 43C
D
A
B
E
1.00

CDABE1.00

Слайд 44C
D
A
B
E
1
1
1
1
0
0
0
0

CDABE11110000

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика