![]() |
![]() |
![]() |
|
Алгоритм сортировки с помощью дерева выбора | ☑ | ||
---|---|---|---|---|
0
queit
05.04.11
✎
17:13
|
Всем доброго времени суток :-)
Расбираюсь с различными (быстрыми) алгоритмами сортировки, и нашел интересный алгоритм "Алгоритм сортировки с помощью дерева выбора" (древесной сортровки), но реализации его нет, пытаюсь сам реализовать, хотя бы псевдокод. Алгоритм очень похож на пирамидальную сортировку (полное описание метода 'древесной сортровки' можно найти, например, у H. Вирта в книге 'Алгоритмы + Структуры Данных = Программы'.), но строится не представление данных в виде дерева, а 'дерево выбора' (т.е. данные должны храниться в одном массиве). В качестве примера: есть массив (3,1,3,4,5,1,7,4), Сортировка начинается с построения дерева выбора: просматриваются пары элементов (i+1),(i+2) и минимальный становится родителем пары, затем просматриваются пары родителей и т.д. пока не будет найден минимальный элемент. Структура поддерева такая i - родитель, 2i+1 и 2i+2 сыновья. В итоге дерево будет иметь вид: 1 1 1 1 3 1 4 3 1 3 4 5 1 7 4 Мои мысли по этому поводу: должна быть какая-то рекурсивная функция, которая проходит по уровням и сравнивает пары. Как запустить рекурсию я не знаю. Предлагаю вместе подумать над реализацией. Буду рад все присоединившимся ;-) |
|||
1
acsent
05.04.11
✎
17:15
|
зачем нам думать?
|
|||
2
Defender aka LINN
05.04.11
✎
17:18
|
"Как запустить рекурсию я не знаю".
Мда... Как алгоритмы с деревьми строить - это мы запросто. А как сделать рекурсию - все, приплыли... |
|||
3
vs84
05.04.11
✎
17:39
|
(0)[Как запустить рекурсию я не знаю.]
Рекурсия(); |
|||
4
NikVars
05.04.11
✎
17:41
|
(0) Тут искал?
http://algolist.manual.ru/ |
|||
5
queit
05.04.11
✎
19:28
|
(1) можешь не думать, разрешаю :-)
(2,3) а что-нибудь по сути сказать есть или только флуд??? :-))) |
|||
6
queit
05.04.11
✎
19:32
|
(4) спасибо. смотрел, там описана пирамидальная сортировка.
с ней более-менее все понятно - смысл в том что максимальный (минимальный) элемент как бы всплывает на поверхность (т.е. берется элемент и двигается, пока не станет максимумом, либо меньше максимального), а тут элементы сравниваются парами |
|||
7
zak555
05.04.11
✎
19:36
|
если есть сыновья, то где дочери ?
|
|||
8
queit
05.04.11
✎
19:57
|
(7) ладно-ладно, уговорил чертяка :-) можешь быть дочерью :-)))
|
|||
9
Reaper_1c
05.04.11
✎
20:03
|
реккурсия? в 1С? ну-ну...
|
|||
10
Lys
05.04.11
✎
20:06
|
Чтобы запустить рекурсию, надо (вы не поверите) - запустить рекурсию...
|
|||
11
Ork
05.04.11
✎
20:07
|
УсЁ есть здесь wiki:Tree_sort
|
|||
12
Reaper_1c
05.04.11
✎
20:12
|
(10) да не в этом дело даже... автор же хочет ускориться... только не понимает, что язык 1С не предназнячен для построения простых алгоритмов. Пусть хотя бы число Пи посчитает - на определенном уровне вложенности рекурсии платформа упадет просто. Какое там ускорение, когда среда падает от таких режимов?
|
|||
13
queit
05.04.11
✎
20:15
|
(9) да почему в 1с?! секция "Математика и алгоритмы"
просто хотя бы написать псевдокод, как это должно работать. вот у меня есть мысли что нужно проходить по уровням, а затем по элементам уровней, вот только не могу сообразить как допустим выходить из рекурсии - когда индекс на уровне за пределами массива или заранее считать кол-во элементов на уровне, но это уже не секурсия |
|||
14
queit
05.04.11
✎
20:15
|
(10)ну а по сути что-нибудь есть?!
|
|||
15
queit
05.04.11
✎
20:16
|
(11) это немного не то
в задаче, которую я описал строится некое дерево минимумов (максимумов) |
|||
16
queit
05.04.11
✎
20:17
|
(12) да я еще раз говорю - я не слова не сказал про 1с
для начала хотя бы написать псевдокод. |
|||
17
zak555
05.04.11
✎
20:17
|
бинарное дерево - уже отсортированное
|
|||
18
Ork
05.04.11
✎
20:20
|
(15) "строится некое дерево минимумов (максимумов)" И что? Чем это отличается от построения бинарного дерева? Что находится в узлах оного по вашему мнению?
|
|||
19
queit
05.04.11
✎
20:20
|
(17) в усовии задачи нет слова "бинарное дерево".
ради интереса открой Вирта 'Алгоритмы + Структуры Данных = Программы'. Там описана пирамидальная сортировка достаточно подробно с псевдокодом, а про сортировку деревом выбора "слегка" написано. Вот я и хочу разобраться как это делается. Своими силами не получается, вот и вынес задачу на суд общественности |
|||
20
queit
05.04.11
✎
20:22
|
(18) вот допустим описание: http://citforum.ru/programming/theory/sorting/sorting1.shtml#2_5
вот как его построить??? и это не бинарное дерево, т.к. оно не сотрированное |
|||
21
zak555
05.04.11
✎
20:25
|
(19) ты дурак или как ?
" Сортировка пирамидой использует сортирующее дерево. Сортирующее дерево — это такое двоичное дерево, у которого выполнены условия: 1. Каждый лист имеет глубину либо d, либо d ? 1, d — максимальная глубина дерева. 2. Значение в любой вершине больше, чем значения её потомков. " wiki:Heapsort |
|||
22
queit
05.04.11
✎
20:27
|
(21)уважаемый!!! на личности не надо переходить!!!
|
|||
23
zak555
05.04.11
✎
20:28
|
(22) так книжки читай тогда внимательно
|
|||
24
Defender aka LINN
05.04.11
✎
20:29
|
(5) По сути? Ну сам напросился...
"- Вы стоите на самой низшей ступени развития! - перекричал Филипп Филиппович, - вы еще только формирующееся, слабое в умственном отношении существо, все ваши поступки чисто звериные, и вы, в присутствии двух людей с университетским образованием, позволяете себе с развязностью совершенно невыносимой, подавать какие-то советы космического масштаба и космической же глупости о том, как все поделить, и вы в то же время наглотались зубного порошку!.." Это вот про тебя. |
|||
25
Reaper_1c
05.04.11
✎
20:32
|
Бог ты мой, академические изыскания на мисте... во делать нефиг...
|
|||
26
queit
05.04.11
✎
20:35
|
(23) открой Вирт Н. Алгоритмы и структуры данных страница 108, там описана сортировка с помощью дерева, а дальше про пирамидальную. Еще раз акцентирую, что с пирамидальной более-менее все понятно, а с деревом выбора не понятно.
я по поводу пирамидальной с тобой не спорю, так оно и есть. я спрашиваю у сообщества как быть с построением дерева выбора. |
|||
27
queit
05.04.11
✎
20:36
|
(24) совершенно не понятно к чему это :-)
ты пьяный что ли? а по теме вопроса что-нибудь можешь сказать? :-) |
|||
28
queit
05.04.11
✎
20:38
|
(25) нет, не академические. просто стало интересно...
|
|||
29
NS
05.04.11
✎
20:52
|
Правильное название - корпоративная сортировка.
Во всяком случае нам в далеком 89-ом давали такое название. |
|||
30
queit
05.04.11
✎
20:57
|
(29)серьезно???
|
|||
31
queit
05.04.11
✎
20:58
|
(29) подробнее можете рассказать?
|
|||
32
NS
05.04.11
✎
20:58
|
(30) Да, серьезно.
|
|||
33
queit
05.04.11
✎
21:02
|
(32)спасибо. попробую завтра поискать в лит-ре.
по крайней мере у Вирта и Сэджвика такого названия не встречал. Да и именно про описанный метод в (0) у них мало информации :-( |
|||
34
NikVars
05.04.11
✎
21:05
|
Все больше и больше убеждаюсь в практической ценности всяких сортировок всякими методами.
|
|||
35
NS
05.04.11
✎
21:11
|
Была книга у меня тогда, в которой описывались битовые методы защиты и избыточного кодирования данных (типа кода Хэмминга) и там давалось тоже название (корпоративная) что и давали нам на сборах на союз. Помню что книга - перевод с Японского :)
Сам алгоритм плохо помню, ибо он на практике не применяется (при малых размерах массива быстрее Шелл, при больших - всякие квиксорты, слияние отрезков и т.д.) Но тогда тоже помню что с пониманием корпоративной сортировки у меня возникли некоторые проблемы. (нужно было выучить за вечер, а на вечер еще и кучу задач ежедневно давали) Но вроде выучил, и на следующий день написал. |
|||
36
NS
05.04.11
✎
21:15
|
Сейчас единственно что помню - как массив представляется в виде бинарного дерева (если нумерация с нуля, то у каждого узла I - дочерние - 2i+1 и 2i+2), и что сначала элементы поднимают, потом опускают (или наоборот), то есть алгоритм состоит из двух частей.
|
|||
37
queit
05.04.11
✎
21:16
|
(35)благодарю за инфу.
попробовал погуглить - информации нет. у меня ситуация проще :-) сдавать ничего не надо. сегодня наткнулся на описание этого алгоритма и стало интересно. чем-то он меня зацепил, хочу найти решение :-) |
|||
38
NS
05.04.11
✎
21:22
|
Вроде бы пишется рекурсивная процедура,
которая обрабатывает оба поддерева, и больший элемент пишет вверх. то есть первый запуск Поднять(0), а в нем Процедура Поднять(i) Если i>maxIndex Тогда Возврат; КонецЕсли; Поднять(2*i+1); Поднять(2*i+2); //И тут больший пишется в узел I. КонецПроцедуры Это типа первая или вторая часть алгоритма, котораязапускается несколько раз, пока изменений в дереве не будет, и есть типа даказательство что запускать придется не более чем Log N раз. Сейчас покурю, попробую точно вспомнить алгоритм, хотя нужен был он мне только один раз, и больше 20-ти лет назад, поэтому вспомнить будет тяжело. |
|||
39
queit
05.04.11
✎
21:24
|
(36) она везде написана что у вирта, что у сэджвика на уровне: "С помощью n/2 сравнений можно определить наименьший элемент из каждой пары, при помощи следующих n/4 — наименьший из каждой пары таких наименьших ключей и т.д. При этом за n-1 сравнений мы можем построить дерево выбора..."
И ни одного толкового объяснения как же это дерево строится — не говоря уже о коде. просто еще у меня мысль родилась - вот пирамидальна она на четном и нечетном кол-ве элементов, а здесь получается на парах должна быть. и как быть в случае с отсутсвием у одного эл-та пары |
|||
40
queit
05.04.11
✎
21:27
|
(38) я по пирамиде разобрался с кодом:
template<class T> void downHeap(T a[], long k, long n) { // процедура просеивания следующего элемента // До процедуры: a[k+1]...a[n] - пирамида // После: a[k]...a[n] - пирамида T new_elem; long child; new_elem = a[k]; while(k <= n/2) { // пока у a[k] есть дети child = 2*k; // выбираем большего сына if( child < n && a[child] < a[child+1] ) child++; if( new_elem >= a[child] ) break; // иначе a[k] = a[child]; // переносим сына наверх k = child; } a[k] = new_elem; } template<class T> void heapSort(T a[], long size) { long i; T temp; // строим пирамиду for(i=size/2-1; i >= 0; i--) downHeap(a, i, size-1); // теперь a[0]...a[size-1] пирамида for(i=size-1; i > 0; i--) { // меняем первый с последним temp=a[i]; a[i]=a[0]; a[0]=temp; // восстанавливаем пирамидальность a[0]...a[i-1] downHeap(a, 0, i-1); } } тут получается просеивание эл-та сквозь пирамиду |
|||
41
NS
05.04.11
✎
21:29
|
(39) Нет пары и нет. какие проблемы? :)
У тебя получается либо только вершина, либо только вершина и левый дочерний узел. |
|||
42
queit
05.04.11
✎
21:29
|
а древесная получается, что есть входной массив размерностью N, итоговое дерево будет размером 2*N-1. Нижний уровень нам тоже известен. это есть ничто иное как входной массив.
осталось выстроить n-1 элемент |
|||
43
queit
05.04.11
✎
21:30
|
(41) да, согласен. или можно отсутствующий в паре элемент заменять на бесконечность
|
|||
44
queit
05.04.11
✎
21:32
|
(42) дальше, как мне кажется, нужно идти по уровням, которых у нас N/2, а затем по элементам уровня, сравнивая пары. вот здесь у меня и затык полный. как должна сработать рекурсия и как из неё выходить, я не понима...
|
|||
45
NS
05.04.11
✎
21:34
|
(44) см (38)
|
|||
46
queit
05.04.11
✎
21:38
|
(45) да, в 40 подобное реализовано.
|
|||
47
queit
13.04.11
✎
14:20
|
Реализовал на с++, публикую для тех кому интересно.
#include <iostream> #include <conio> #include <stdlib.h> #include <stdio.h> #include <math> #include <string.h> #include <stdlib.h> #include <vector> using namespace std; //--------------------------------------------------------------------------- #pragma hdrstop //--------------------------------------------------------------------------- int N; vector <int> arrB, arrC, arrA; int infinity; //--------------------------------------------------------------------------- #pragma argsused void CreateTree(void) { int i,j,L,H,minA,v; //Установка размера выходного массива arrB.resize(N); //Заполнение вспомагательного вектора arrC = arrA; L = log(N)/log(2); //Определяем кол-во уровней for (j = 0; j < L; j++){ //На последнем этапе итерации просто устанавливаем в корень //минимальный элемент на прошлом этапе if (j==(L-1)){ arrB[1] = min(arrB[2],arrB[3]); return; } //Определение размера вспомогательного массива H = arrC.size(); i = 1; while(i < H){ //Итератор для результирующего массива //int v = 0; if (i==1){ v = pow(2, L-j)/2; } else v+=1; //Определение минимального элемента из пары i и i+1 if (arrC[i-1] < arrC[i]){ minA = arrC[i-1]; } else{ minA = arrC[i]; } //Установка мин.значения в результирующий массив arrB[v] = minA; //Добавим во вспомогательный массив мин. элемент arrC.push_back(minA); i=i+2; } //Изменаем размер вспомагательного массива vector<int>::iterator p = arrC.begin(); arrC.erase(p - 1, p - 1 + H); } } //--------------------------------------------------------------------------- void DefineInfinity(void){ int MaxA; MaxA = arrA[0]; for (int i=0; i<N; i++){ if (arrA[i]>MaxA) MaxA = arrA[i]; } infinity = MaxA + 1; } //--------------------------------------------------------------------------- void TreeSort(void){ int k = 0; int i, minA; //int j = 0; while (k < N){ i = 1; if (arrB[i] == infinity) break; //Текущий элемент является минимальным minA = arrB[i]; //Обнуляем текущий элемент arrB[i] = infinity; //Спуск по дереву while (i < 2*N){ if (2*i+1 > 2*N-1){ arrA[k] = minA; arrB[i] = infinity; break; } if (arrB[2*i] == minA){ arrB[i] = infinity; i = 2*i; } else if (arrB[2*i+1] == minA){ arrB[i] = infinity; i = 2*i + 1; } } //Подъем по дереву while(i > 1){ //Определить четность i-го элемента if (i%2 == 1){//Нечетный элемент if (arrB[i] > arrB[i-1]) arrB[(i-1)/2] = arrB[i-1]; else arrB[(i-1)/2] = arrB[i]; } else{//Четный элемент if (arrB[i] > arrB[i+1]) arrB[i/2] = arrB[i+1]; else arrB[i/2] = arrB[i]; }; //Обнуляем текущий элемент //arrB[i] = infinity; i=i/2; } k+=1; //if (k > (N-1)) break; } } //--------------------------------------------------------------------------- void main(void) { //Заполнение исходного вектора arrA.push_back(1); arrA.push_back(3); arrA.push_back(4); arrA.push_back(5); arrA.push_back(1); arrA.push_back(7); arrA.push_back(4); arrA.push_back(3); /*arrA.push_back(1); arrA.push_back(2); arrA.push_back(3); arrA.push_back(4); arrA.push_back(5); arrA.push_back(6); arrA.push_back(7); arrA.push_back(8); arrA.push_back(9); arrA.push_back(10); arrA.push_back(11); arrA.push_back(12); arrA.push_back(13); arrA.push_back(14); arrA.push_back(15); arrA.push_back(16);*/ N = arrA.size(); for (int i=0; i<N-1; i++){ cout << arrA[i] << " | "; } cout << endl; cout << endl; CreateTree(); //Дописываем в конец результирующего массива исходный (нижний уровень в дереве) for (int i=0; i<N; i++) arrB.push_back(arrA[i]); cout << "| "; for (int i=0; i<2*N-1; i++){ cout << arrB[i] << " | "; } cout << endl; cout << "| "; for (int i=0; i<2*N-1; i++){ if (i>9) cout << i << "| "; else cout << i << " | "; } cout << endl; cout << endl; DefineInfinity(); cout << "Infinity = " << infinity << endl; cout << endl; cout << endl; /*int k = 0; for (int i = 1; i < 2*N - 1; i++){ if (TreeSort(i,k)) k+=1; }*/ TreeSort(); for (int i=0; i<N; i++){ cout << arrA[i] << " | "; } cout << endl; getch(); } //--------------------------------------------------------------------------- |
|||
48
queit
13.04.11
✎
14:21
|
Возможно есть более изящная реализация. Моя не претендует на оптимальность и совершенство, я просто реализовал алгоритм.
Еще один момент хочу отметить: алгоритм применим в основном для массивов размерность которых кратна степени 2, т.е. 2^1=2, 2^2=4, 2^3=8, 2^4=16 и т.д. |
|||
49
queit
13.04.11
✎
14:22
|
особый респект NS :-) действительно эта сортировка имеет иное название :-)
|
|||
50
Ёпрст
гуру
13.04.11
✎
14:35
|
(49) у кнута посмотри в 3 томе - мот там тоже описывается, я не помню уже.
|
|||
51
NS
13.04.11
✎
14:38
|
(49) Нашел термин "корпоративная"?
|
|||
52
NS
13.04.11
✎
14:42
|
Вспомнил - еще всплывало иерахия, иерархиями или иерархичная. Слово корпоративная - могло возникнуть из-за нечеткого перевода с японского.
|
|||
53
queit
13.04.11
✎
14:47
|
(51) да, сходил в библиотеку :-) там ксерокопия с какой-то старой книги была...вот там и нашел такой термин.
|
|||
54
queit
13.04.11
✎
14:47
|
(50) спасибо ;-) но не нашел у кнута, может мне не по глазам :-)
|
|||
55
queit
13.04.11
✎
14:48
|
реализация теперь есть :-) с рекурсией заморачиваться не буду. что-то мне эта реализация тяжко далась :-)))
|
|||
56
trdm
13.04.11
✎
14:50
|
все думают, что производство велосипедов бессмысленная трата времени.
На самом деле производство велосипеда - экзамен на профпригодность. |
|||
57
queit
13.04.11
✎
14:51
|
(56) и как думаешь, я профпригоден? или безнадежен??? :-)))
|
|||
58
trdm
13.04.11
✎
14:53
|
(57) нет времени разбираться.
|
|||
59
queit
13.04.11
✎
14:54
|
(58) понятно ;-)
|
|||
60
NS
13.04.11
✎
14:59
|
(57) Вообще - это сложная задача. Насколько я помню единственное что очень тяжело мне (да и остальным участникам сборов) далось на сборах на союз.
то есть вообще давалось не с практической целью, а чтоб голову как следует поломать. |
|||
61
queit
13.04.11
✎
15:06
|
(60) согласен, не тривиальная задачка, не имеющая практического применения...
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |