У моего общего алгоритма QuickSort есть две проблемы, которые я не могу определить причину.QuickSort Stack Overflow
- Список иногда не правильно отсортирован
- При работе со списками больше, чем 20000 пунктов, я часто получаю переполнение стека, если значения повторяют много (который я полагаю, не должна быть реальной проблемой)
Список, который не сортируется правильно, является довольно редким случаем, поэтому список должен быть достаточно большим. В пасте внизу показаны первые 13 элементов 172-элементного списка установленного программного обеспечения с первым столбцом, отображающим результат после первого сортировки, и второй столбец для второго сортировки.
Adobe AIR 7-Zip 4.65 (x64 edition)
7-Zip 4.65 (x64 edition) Adobe AIR
Adobe Community Help Adobe Community Help
Adobe Encore CS4 Codecs Adobe Encore CS4 Codecs
Adobe Media Encoder CS4 Exporter Adobe Media Encoder CS4 Exporter
Adobe Media Encoder CS4 Importer Adobe Media Encoder CS4 Importer
Adobe Media Player Adobe Media Player
Adobe Reader X (10.1.0) Adobe Reader X (10.1.0)
Adobe Setup Adobe Setup
Adobe Setup Adobe Setup
Apple Application Support Adobe Setup
Adobe Setup Apple Application Support
Apple Mobile Device Support Apple Mobile Device Support
... ...
Как вы можете видеть, первый раз он был отсортирован, есть некоторое неправильное поведение, которое фиксируется делают другой вид.
Вторая проблема с переполнением стека происходит, если я сортирую свой список журналов событий Windows с большим олом. Кажется счастливым, если я сортирую 52 000 дат, охватывающих 4 недели; но если я сортирую 52 000 идентификационных номеров, которые имеют много повторов, мой размер стека становится 998 элементов задолго до того, как он выйдет из строя. Это также происходит, если я сортирую 30 000 длинный список столбцом, который в основном «gupdate».
Теперь, насколько я вижу, счетчик стека должен быть log2 (n), потому что сумма, добавленная в стек, равна количеству разрезанной половины.
Я сделал свой случайный случайный, чтобы помочь этому эффекту, но это не сильно изменило ситуацию.
Log2 (60000) = 16. Этого недостаточно для переполнения стека!
Это код в беспокойстве:
private static void QuickSortFunction<T>(T[] array, int start, int end, Comparer<T> comparer)
{
if (end - start >= 1)
{
int leftPtr, rightPtr, pivot;
Random random = new Random();
pivot = random.Next(start, end);
Swap(array, pivot, start);
pivot = start;
leftPtr = start + 1;
rightPtr = end;
while (leftPtr < rightPtr)
{
while ((comparer.Compare(array[leftPtr], array[pivot])) <= 0 && (leftPtr < rightPtr))
{
leftPtr++;
}
while ((comparer.Compare(array[rightPtr], array[pivot])) >= 0 && (leftPtr <= rightPtr))
{
rightPtr--;
}
if (leftPtr < rightPtr)
{
Swap(array, leftPtr, rightPtr);
}
}
Swap(array, pivot, rightPtr);
pivot = rightPtr;
QuickSortFunction(array, start, pivot - 1, comparer);
QuickSortFunction(array, pivot + 1, end, comparer);
}
}
private static void Swap<T>(T[] array, int pointer1, int pointer2)
{
T temp = array[pointer1];
array[pointer1] = array[pointer2];
array[pointer2] = temp;
}
Для тех, кто заинтересован, это исправления для глюка испорченных. В принципе, он не смог распознать массив из двух элементов, когда он вышел из строя. Например, {E, B}, который он не изменит, потому что он не будет смотреть на свой собственный стержень.
if (end - start >= 1)
{
int leftPtr, rightPtr, pivot;
Random random = new Random();
pivot = random.Next(start, end);
Swap(array, pivot, start);
pivot = start;
leftPtr = start;
rightPtr = end;
while (leftPtr < rightPtr)
{
while ((comparer.Compare(array[leftPtr], array[pivot])) < 0 && (leftPtr < rightPtr))
{
leftPtr++;
}
while ((comparer.Compare(array[rightPtr], array[pivot])) >= 0 && (leftPtr < rightPtr))
{
rightPtr--;
}
if (leftPtr < rightPtr)
{
Swap(array, leftPtr, rightPtr);
}
}
Swap(array, pivot, rightPtr);
pivot = rightPtr;
QuickSortFunction(array, start, pivot - 1, comparer);
QuickSortFunction(array, pivot + 1, end, comparer);
}
Будет обновляться после того, как я напишу решение для переполнения стека.
P.s, есть ли опрятный способ подсчета моего стека для сортировки дат 52 000 в Visual Studio? – CJxD
Немного помимо точки: не создавайте экземпляр «Случайный» в цикле (или рекурсии). Используйте статическое поле класса и инициализируйте его только один раз. – Joey
Есть ли причина, по которой вы хотите написать свою собственную быструю сортировку вместо использования встроенного алгоритма быстрой сортировки в Array.sort? – BlueMonkMN