为什么我的HeapSort跳过数组中的第一个元素
Why is my HeapSort skipping the first element in the array?
我在我的算法类中实现了一个赋值的HeapSort,我终于完成了,但由于某种原因,排序跳过了数组中的第一个元素。
原数组:
int heapArray[SIZE] = { 5 ,99, 32, 4, 1, 12, 15 , 8, 13, 55 };
HeapSort()后的输出
5 99 32 15 13 12 8 4 1
我看了所有的函数,不明白为什么它跳过了第一个元素。有人能帮我吗?我包含了下面所有的HeapSort函数。我知道它看起来很多,但我太接近了。
int main()
{
int heapArray[SIZE] = { 5 ,99, 32, 4, 1, 12, 15 , 8, 13, 55 };
HeapSort(heapArray);
return 0;
}
.........................................................................................
void HeapSort(int heapArray[])
{
int heap_size = SIZE;
int n = SIZE;
int temp;
Build_Max_Heap(heapArray);
for(int i = n-1; i >= 2; i--)
{
temp = heapArray[1];
heapArray[1] = heapArray[i];
heapArray[i] = temp;
heap_size = heap_size-1;
Max_Heapify(heapArray,1);
}
return;
}
...........................................................................................
void Build_Max_Heap(int heapArray[])
{
double n = SIZE;
for(double i = floor((n-1)/2); i >= 1; i--)
{
Max_Heapify(heapArray,i);
}
return;
}
...........................................................................................
void Max_Heapify(int heapArray[],int i)
{
int n = SIZE;
int largest = 0;
int l = Left(i);
int r = Right(i);
if(( l <= n) && (heapArray[l] > heapArray[i]))
{
largest = l;
}
else
{
largest = i;
}
if( (r <= n) && ( heapArray[r] > heapArray[largest]))
{
largest = r;
}
int temp;
if(largest != i)
{
temp = heapArray[i];
heapArray[i] = heapArray[largest];
heapArray[largest] = temp;
Max_Heapify(heapArray,largest);
}
return;
}
...........................................................................................
int Parent(int i)
{
return (i/2);
}
int Left(int i)
{
return (2*i);
}
int Right(int i)
{
return ((2*i)+1);
}
您的代码中有几个问题:
首先:数组的索引从0开始,而不是从1开始,因此,索引错误的地方很多,如下所示:
HeapSort函数:
for(int i = n-1; i >= 2; i--) {
//should be 1 not 2
temp = heapArray[1]; //should be 0 not 1 in those 2 statements
heapArray[1] = heapArray[i];
heapArray[i] = temp;
}
Max_Heapify(heapArray,1);
//should start from 0 not 1
除了:for(double i = floor((n-1)/2); i >= 1; i--)
{ //should start from 0 not 1
Max_Heapify(heapArray,i);
}
You Parent, Left和Right有类似的错误,你可以看到上面两个帖子。
同时,你有逻辑错误在你的HeapSort和max_heapify函数。您定义了heap_size并更新了它,但从未真正使用过它。您必须将其传递给Max_Heapify函数。因为每次当您将当前最大的元素放到数组的末尾时,您只需要对剩余的元素进行堆积,而不再需要对整个堆进行堆积。这也意味着您的heapify函数有错误,因为您从未真正使用过heap_size。正确的HeapSort和Max_Heapify以及Build_Max_Heap函数应该是:
堆排序:
void HeapSort(int heapArray[])
{
//do what you did before this sentence
Build_Max_Heap(heapArray,heap_size);
//need to pass heap_size since Max_Heapify use heap_size
for(int i = n-1; i >= 1; i--)
{
//...same as you did but pay attention to index
heap_size = heap_size-1;
Max_Heapify(heapArray,0,heap_size); //remember to use heap_size
}
//you declared void, no need to return anything
}
Build_Max_Heap功能:
void Build_Max_Heap(int heapArray[], int heapSize) //should use heapSize
{
int n = SIZE;
for(int i = floor((n-1)/2); i >= 0; i--) //here should be 0 not 1
{
Max_Heapify(heapArray,i,heapSize); //should use heapSize
}
}
Max_Heapify功能:
void Max_Heapify(int heapArray[],int i, int heap_size) //should use heap_size
{
//....here similar to what you did
if(( l < heap_size) && (heapArray[l] > heapArray[i]))
{ //^^compare with heap_size not SIZE
//skip identical part
}
if( (r < heaps_ize) && ( heapArray[r] > heapArray[largest]))
{
//same error as above
}
//skip identical part again
Max_Heapify(heapArray,largest, heap_size); //have to use heap_size
}
}
您可能需要从伪代码中更好地理解HeapSort算法。
here
Build_Max_Heap(heapArray);
for(int i = n-1; i >= 2; i--)
{ ^^^^^
temp = heapArray[1];
heapArray[1] = heapArray[i];
heapArray[i] = temp;
heap_size = heap_size-1;
Max_Heapify(heapArray,1);
}
return;
}
在i=2时停止循环,将其减为1,不取heapArray的第一个元素它的索引是0
Parent
, Left
和Right
函数适用于基于1的数组。对于基于0的,您需要使用:
int Parent(int i)
{
return (i - 1) / 2;
}
int Left(int i)
{
return (2 * i) + 1;
}
int Right(int i)
{
return 2 * (i + 1);
}
您可以在示例堆中检查:
0
/
1 2
/ /
3 4 5 6
- 如何实现 Front() 方法以返回模板化双向链表C++的第一个元素?
- 对的排序向量 (std::vector<pair<int, int>>) 按对的第一个元素搜索并更新第二个元素值
- C++ queue.front();为什么不从第一个元素开始呢?
- 指向数组基址的指针而不是指向第一个元素的指针有什么优点?
- 静态堆栈函数不会 1) 输入第一个元素 2)添加新元素时识别旧元素
- 从队列中删除第一个元素C++
- 如果第一个元素包含任何零,则我的程序以不希望的方式运行
- 为什么数组不打印第一个元素?
- 在数组中显示第一个元素用户输入
- 消除集合的第一个元素
- 为什么指向矢量第一个元素的指针会丢失?
- 如何打印出常量字符串的第一个元素?
- 读取数组的第一个元素还是第 4000 个元素更快?
- 如何在数组的一部分中查找特定值的第一个元素
- 对数组进行排序的算法,先是第一个元素,然后是前 2 个元素,然后是前 3 个元素,依此类推
- 访问指向对象指针向量的指针的第一个元素?
- 引用保留向量中的第一个元素
- 指向数组的指针是否应该等于指向其第一个元素的指针?
- 尝试将参数包的第一个元素作为函数调用,并将包的其余部分作为参数传递给它
- 代码是否有效.如果我想显示第一个元素?如果不是,那么 s.begin() 会返回什么?