Теория: Общая информация изложена здесь
Практика: informatics.mccme.ru
Реализация:
В своей реализации эта сортировка использует структуру данных: бинарное дерево, каждый элемент которого можно описать следующим образом:
- struct tree
- {
- tree* left; // левый сын
- tree* right; // правый сын
- int value; // значение
- };
* This source code was highlighted with Source Code Highlighter.
Само бинарное дерево удобно формировать по мере поступления новых данных, например при считывании данных из файла или с консоли.
Каждый элемент дерева соответствует двум правилам:
1. Значение левого сына строго меньше значения родителя
2. Значение правого сына не меньше значения родителя
При добавлении нового элемента в дерево происходит его просейка вниз, начиная с корня по следующим правилу:
Если новый элемент меньше текущего узла, то перенаправляем его в левое поддерево, иначе в правое. Повторяем этот шаг до тех пор, пока не окажемся в пустом листе дерева. Это и будет место нового элемента.
Проилюстрируем это следующими функциями:
- void add_to_tree(tree* &node, int value)
- {
- if (node == NULL)
- {
- node = new tree(value);
- return;
- }
- if (node->value > value)
- add_to_tree(node->left,value);
- else
- add_to_tree(node->right,value);
- }
- void input_tree(tree* &root)
- {
- cin>>n;
- for (int i=0;i<n;i++)
- {
- scanf("%d",&value);
- add_to_tree(root,value);
- }
- }
* This source code was highlighted with Source Code Highlighter.
После того, как дерево сформировано, осталось вывести ответ.
Если организовать обход по правилу:
левый сын – родитель – правый сын
и последовательно выводить значения родителя, то получим отсортированный массив:
- void output_tree(tree* node)
- {
- if (node == NULL)
- return;
- output_tree(node->left);
- printf("%d ",node->value);
- output_tree(node->right);
- }
* This source code was highlighted with Source Code Highlighter.
Полный исходник лежит здесь
Как видно на каждый элемент входного массива в дереве тратиться дополнительно 8 байт на указатели на сыновей. Этот дополнительный расход памяти делает этот метод менее привлекательным. Но тем не менее саму идею использования дерева можно применить в других прикладных задачах.
Данный метод без балансировки дерева будет квадратичным. Если взять например уже отсортированный массив или реверс отсортированный.
ОтветитьУдалитьБалансировку рассамотрим, когда будем разбирать работу с двоичным дерева поиска
ОтветитьУдалитьЗамечание по поводу:
ОтветитьУдалитьКаждый элемент дерева соответствует двум правилам:
1. Значение левого сына строго меньше значения родителя
2. Значение правого сына не меньше значения родителя
Не совсем так, правильнее: Корень больше любого элемента из левого поддерева и не больше любого элемента из правого поддерева.