Нет необходимости дважды повторять массив. Если вас не волнует порядок ненулевых объектов (в частности, если они не должны оставаться в одном и том же относительном порядке), вы можете сделать это очень просто:
int end = theHeap.length;
for (int i = 0; i < end; ++i) {
while (theHeap[i] == null && i < end) {
--end;
theHeap[i] = theHeap[end];
theHeap[end] = null;
}
}
Поскольку каждая итерация цикла (внешняя или внутренняя) уменьшает (end - i)
на единицу и цикл заканчивается, когда они встречаются, это алгоритм O (N).
РЕДАКТИРОВАТЬ Пересмотренная версия, которая позволяет не менять местами нули (возможно, немного более эффективно):
int end = theHeap.length;
for (int i = 0; i < end; ++i) {
if (theHeap[i] == null) {
while (--end > i && theHeap[end] == null) {
// loop
}
if (i < end) {
theHeap[i] = theHeap[end];
theHeap[end] = null;
}
}
}
EDIT 2 Гораздо более простая версия, которая также поддерживает начальный порядок сортировки ненулевых элементов:
int next = 0;
for (int i = 0; i < theHeap.length; ++i) {
if (theHeap[i] != null) {
if (i > next) {
theHeap[next] = theHeap[i];
theHeap[i] = null;
}
++next;
}
}