所以我一直在玩着#34;着名的"排序算法,以查看它们对数组进行排序的步骤。但是我被困在Heapsort上,我无法弄清楚如何正确计算步数。通过我的实现,对128个长数组进行排序平均需要630步 - 这比nlog(n)要多得多。使用quicksort对相同的数组进行排序时,它大约是260-280,这几乎就是nlogn,这告诉我heapsort的计数器是错误的。这是我目前的代码:
public static int heapify(double[] heap, int size, int index, bool asc, int steps)
{
int left = (index + 1) * 2 - 1;
int right = (index + 1) * 2;
int largest = 0;
int stepCounter = steps;
//For ascending sorting
//Note: ideally there should be a maxHeapify for ascending and minHeapify for descending sorting seperately
//however in this case it is easy to see what is happening
if(asc)
{
if (left < size && heap[left] > heap[index])
{
largest = left;
}
else
{
largest = index;
}
if (right < size && heap[right] > heap[largest])
{
largest = right;
}
} else
{//For descending sorting
if (left < size && heap[left] < heap[index])
{
largest = left;
}
else
{
largest = index;
}
if (right < size && heap[right] < heap[largest])
{
largest = right;
}
}
if (largest != index)
{
double temp = heap[index];
heap[index] = heap[largest];
heap[largest] = temp;
stepCounter++;
stepCounter = heapify(heap, size, largest, asc, stepCounter);
}
return stepCounter;
}
public static void heapSort(double[] heap, bool asc, int steps = 0)
{
int size = heap.Length;
int i;
int stepCounter = steps;
//Build heap
for (i = (size - 1) / 2; i >= 0; i--)
{
stepCounter = heapify(heap, size, i, asc, stepCounter);
}
for(i = heap.Length - 1; i > 0; i--)
{
double temp = heap[i];
heap[i] = heap[0];
heap[0] = temp;
size--;
stepCounter = heapify(heap, size, 0, asc, stepCounter);
}
Console.WriteLine("Heap sort has taken {0} steps", stepCounter);
}
感谢。 需要说明的是:我最后只需要一个语句,打印所有步骤的数量,而不是大量的消息,每个步骤2-3步。
编辑: 我像这样改变了代码:
public static int heapify(double[] heap, int size, int index, bool asc, int steps)
{
int stepCounter = 0;
if (largest != index)
{
double temp = heap[index];
heap[index] = heap[largest];
heap[largest] = temp;
stepCounter++;
heapify(heap, size, largest, asc, stepCounter);
}
return stepCounter;
}
public static void heapSort(double[] heap, bool asc, int steps = 0)
{
int stepCounter = steps;
//Build heap
for (i = (size - 1) / 2; i >= 0; i--)
{
stepCounter += heapify(heap, size, i, asc, stepCounter);
}
for(i = heap.Length - 1; i > 0; i--)
{
double temp = heap[i];
heap[i] = heap[0];
heap[0] = temp;
size--;
stepCounter += heapify(heap, size, 0, asc, stepCounter);
}
Console.WriteLine("Heap sort has taken {0} steps", stepCounter);
}
(删除不相关的位)。有了这个,我平均得到128个长度数组160-170,长度约1000个数组约1300步。我认为这听起来很合理。谢谢@jdweng
答案 0 :(得分:4)
但是我被困在Heapsort上,我无法弄清楚如何正确计算步数。通过我的实现,对128个长数组进行排序平均需要630步 - 这比nlog(n)要多得多。使用quicksort对相同的数组进行排序时,它大约是260-280,这几乎就是nlogn,这告诉我heapsort的计数器是错误的。
这段经文表明你不懂大O符号。
当我们说f(n) = O(g(n))
时,我们的意思是存在常量k
和N
,如果N < n
那么|f(n)| < k |g(n)|
。换句话说,&#34;增长模式并不比g(n)
&#34;更差。它没有提到常数。而对于小数字的表现一无所知。
现在heapsort和quicksort都是O(n log(n))
。但是它们有不同的常数。 Quicksort得名,因为它平均比mergesort和quicksort等替代品快得多。你看到的恒定差异反映了这一点。
但是,我会在n
上收集有关多个值的数据并生成图f(n)/(n log(n))
。