HeapSort.pas 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. Program HeapSort;
  2. {Ну что, дождались вы и этой чертовой пирамидальной сортировки
  3. Я все-таки врубился как там что. Оказалось еще более сложно чем казалось
  4. вначале. Основная идея:
  5. - Дерева никакого нет, и не было!
  6. - Зато эта долбаная пирамида соществует в твоем мозгу
  7. С САМОГО НАЧАЛА В ПОЛНОМ РАЗМЕРЕ!
  8. - Ну и типа мы с нижних рядов едем в верх, на каждом шаге
  9. просеивая текущий эл-т через пирамиду (см. Н. Вирта)
  10. - Таким хреном отехав с середины до самого верха, т.е. просеив все эл-ты
  11. мы получили эту долбанную пирамиду, с условием что два сина всегда
  12. больше отца!
  13. - Потом - совершенно другой этап: сама сортировка и есть.
  14. 1) Т.к. пирамида удовлетворяет усл. (A[i] < A[2i]) AND (A[i] < A[2i+1])
  15. значит A[1] - самый маленький элемент !
  16. 2) Ну мы его и пихаем в последний эл-т пирамиды, а его - в голову и
  17. просеиваем. Таким образом на верху - опять самый маленький.
  18. И при этом уменшаем длину нашей пирамиды на 1
  19. 3) Пока наша пирамида еще не пустая повторяем.
  20. 4) Таким хреном - у нас обратно отсортированный массив. Ну все сравнения
  21. - наоборот - вот тебе и прямая сортировка!
  22. PS. попробую это в коде откомментировать ;)
  23. }
  24. CONST
  25. ArLen = 10;
  26. TYPE
  27. Index = 1..ArLen;
  28. Item = word;
  29. VAR
  30. Pir : array [1..ArLen] of Item;
  31. Procedure Sift(L,R:word);{Блин! Sift - просеивать по англицки!}
  32. var
  33. i, j : Index;
  34. x : Item;
  35. {В этой процедуре самое важное - L и R, они отвечают не просто зи индексы,
  36. а еще говорят о том, какая часть пирамиды сейчас реально рассматривается}
  37. begin
  38. i := L; {Тот, который меняем}
  39. j := 2*i; {На кого можно менять}
  40. x := Pir[L]; {Кого просеиваем}
  41. if (j<R) AND (Pir[j] < Pir[J+1]) then Inc(j); {Выберем наибольшего потомка}
  42. while (j<=R) and (x < Pir[j]) do
  43. begin
  44. Pir[i] := Pir[j]; {Обменяли, достаточно просто заменить себя на своего сына
  45. т.к сам - x и он никуда не денется}
  46. i := j; {Спустились}
  47. j := 2*i;
  48. if (j<R) AND (Pir[j] < Pir[J+1]) then Inc(j); {Выберем наибольшего потомка}
  49. end;
  50. Pir[i] := x; {Ну вот и вернем x на место}
  51. {Я НЕ ПОНИМАЮ ПОЧЕМУ ЭТОЙ СТРОКИ НЕТ В ВИРТЕ }
  52. end;{Sift}
  53. {-------------------------}
  54. VAR
  55. L,R : index;
  56. x : item;
  57. BEGIN
  58. Randomize;
  59. for l := 1 to ArLen do Pir[l] := Random(200);
  60. L := ArLen Div 2 + 1; {Идея - нижняя часть - не требует просевки}
  61. R := ArLen;
  62. while L>1 do
  63. begin
  64. Dec(L);
  65. Sift(L,R);
  66. end;
  67. While R > 1 do
  68. begin
  69. x := Pir[R];
  70. Pir[R]:=Pir[1]; {Идея о впихивании верхнего в конец пирамиды}
  71. Pir[1] := x;
  72. Dec(R);
  73. Sift(L,R);
  74. end;
  75. for l := 1 to ArLen do WriteLn(Pir[l]);
  76. END.