Какой самый быстрый способ (по крайней мере в теории) сортировать кучу? - PullRequest
2 голосов
/ 22 сентября 2008

Куча - это список, к которому относится следующее:

l[i] <= l[2*i] && l[i] <= [2*i+1]

для 0 <= i < len(list)

Я ищу сортировку на месте.

Ответы [ 6 ]

2 голосов
/ 22 сентября 2008

Просто используйте сортировку кучи. Это на месте. Это был бы самый естественный выбор.

Вы также можете просто использовать свою кучу и сортировать ее другим алгоритмом. После этого вы перестраиваете свою кучу из отсортированного списка. Quicksort - хороший кандидат, потому что вы можете быть уверены, что он не будет работать в наихудшем порядке O (n²) просто потому, что ваша куча уже предварительно отсортирована.

Это может быть быстрее, если ваша функция сравнения стоит дорого. Сортировка кучи имеет тенденцию оценивать функцию сравнения довольно часто.

1 голос
/ 22 сентября 2008

Ну, вы уже на полпути через сортировку кучи, имея ваши данные в куче. Вам просто нужно реализовать вторую часть алгоритма сортировки кучи. Это должно быть быстрее, чем использование быстрой сортировки в массиве кучи.

Если вы чувствуете себя смелым, вы можете попробовать smoothsort , что быстрее, чем heapsort для почти отсортированных данных.

0 голосов
/ 22 сентября 2008

Для сортировки на месте следует самый быстрый способ. Остерегайтесь ошибок в моем коде. Обратите внимание, что этот метод дает перевернутый отсортированный список, который необходимо изменить на последнем шаге. Если вы используете максимальную кучу, эта проблема исчезнет.

Общая идея ясна: поменяйте местами наименьший элемент (с индексом 0) с последним элементом в куче, разбейте этот элемент вниз, пока свойство кучи не восстановится, уменьшите размер кучи на единицу и повторите.

Это не самый быстрый способ сортировки не по месту, поскольку Дэвид Маккей демонстрирует здесь - вы можете добиться большего успеха, поместив элемент, который с наибольшей вероятностью окажется самым маленьким в верхней части кучи вместо одного из нижнего ряда.

Сложность по времени - T (n.log n), наихудший случай - n итераций с возможным log n (высотой кучи) проходит через цикл while.

for (int k=len(l)-1;k>0;k--){
swap( l, 0, k );
while (i*2 < k)
  {
int left = i*2;
int right = l*2 + 1;
int swapidx = i;
if ( l[left] < l[right] )
  {
    if (l[i] > l[left])
      {
    swapidx = left;
      }
  }
else
  {
    if (l[i] > l[right])
      {
    swapidx = right;
      }
  }

if (swapidx == i)
  {
    // Found right place in the heap, break.
    break;
  }
swap( l, i, swapidx );
i = swapidx;
  }}

// Now reverse the list in linear time:
int s = 0; 
int e = len(l)-1;
while (e > s)
  {
    swap( l, s, e );
    s++; e--:
  }
0 голосов
/ 22 сентября 2008

Поскольку у вас уже есть куча, не могли бы вы просто использовать вторую фазу сортировки кучи ? Он работает на месте и должен быть красивым и эффективным.

0 голосов
/ 22 сентября 2008

Сортировка кучи на месте звучит как работа для Сортировка кучи .

Я предполагаю, что память ограничена, возможно, встроенное приложение?

0 голосов
/ 22 сентября 2008

Читайте предметы с вершины кучи по одному. По сути, у вас есть куча сортировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...