#define HEAP_MAX_SIZE 100
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int size;
int heap[HEAP_MAX_SIZE];
int printcounter=0;
void swap(int *a, int *b)
{
int temp = *b;
*b = *a;
*a = temp;
}
/*
*max_heap() performs creates a max heap. (the printf in comments were used for debugging)
*/
void max_heap(int key)
{
int leftkey = (2*key) +1;
int rigtkey = (2*key) +2;
//printf("key is: %d left child index is: %d right child index is: %d \n", key, leftkey, rigtkey);
//printf("value at key is: %d left child is: %d right child is: %d \n", heap[key], heap[leftkey], heap[rigtkey]);
if (key >= 0){
if (leftkey < size && leftkey != size){
if (heap[leftkey] > heap[key]){ printf("If %d > %d\n", heap[leftkey], heap[key]);
printf("Swap %d and %d\n", heap[leftkey], heap[key]);
swap(&heap[leftkey], &heap[key]);
max_heap(key+1);
}
}
if (rigtkey < size && rigtkey != size){
if (heap[rigtkey] > heap[key]){ printf("If %d > %d\n", heap[rigtkey], heap[key]);
printf("Swap %d and %d\n", heap[rigtkey], heap[key]);
swap(&heap[rigtkey], &heap[key]);
max_heap(key+1);
}
}
if (heap[leftkey] < heap[key] && heap[rigtkey] < heap[key]){
max_heap(key-1);
}
}
}
/**
* heapDelete() removes the biggest integer in the heap and returns it.
*
*/
int heapDelete()
{
int largest;
int i;
max_heap(size/2);
largest = heap[0];
///Shifting the array so the first value is gone. (Should have used a link list instead of an array)
for (i=0;i<size;i++){
heap[i] = heap[i+1];
}
size--;
printf("Just deleted: %d\n", largest);
return largest;
}
/**
* addHeap(thing2add) adds the "thing2add" to the Heap.
*
*/
void addHeap(int thing2add)
{
if (size == HEAP_MAX_SIZE)
{
fprintf(stderr, "Inputing too many values, increase HEAP_MAX_SIZE in intHeap.ca\n");
}
else
{
heap[size] = thing2add;
size++;
}
}
堆数组是{1 5 68 56 2 13 8 5 4 6 3 58 4 3 21 5}
刚刚删除:1
如果21&gt; 5
交换21和5
如果58&gt; 13
交换58和13
如果4&gt; 2
交换4和2
....(你明白了)....
刚删除:4
刚删除:4
刚删除:3
刚删除:3
刚删除:2
交换很好,删除很好。但是1被忽略了。此外,程序应该在说出第一个“已删除:”printf之前完成max_heap()。为什么它首先执行printf?它与stdder有关吗?
但这并不是一直发生的。如果我输入一个小集合:1 5 89 23 4或100 5 9 4 56 8该程序可以正常工作。
这是主要的:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
extern int pop();
extern void push(int);
extern void addHeap(int);
extern int heapDelete();
extern void printHeap();
int main(int argc, char * argv[])
{
int value;
int size=0;
int i=0;
while (scanf("%d\n", &value) != EOF) {
fprintf(stderr, "READING INPUT: %d\n", value);
size++;
addHeap(value);
}
/*to print the heap in XML format*/
printHeap();
/*Print ends here*/
/*print the heap in descending order, followed by ascending order (by pushing and popping from a stack)*/
for (i=0;i<size;i++){
push(heapDelete());
}
for (i=0;i<size;i++){
printf("%d ", pop());
}
exit(0);
/*Decsending and Ascending order ends here*/
}
答案 0 :(得分:1)
我已经使用了您的代码,需要注意的一点是parent
,left child
和right child
必须连续才能正常工作:
parent at position i
left child at position i + 1
right child at position i + 2
同样在您的示例{1 2 3}
中,输出也必须排序{3 2 1}
而不是{3 1 2}
。
所以,如果你改变了
int leftkey = (2 * key) + 1;
int rigtkey = (2 * key) + 2;
到
int leftkey = key +1;
int rigtkey = key +2;
按预期工作
瓦尔特
答案 1 :(得分:0)
不是集合的大小导致问题,例如,您的代码不适用于{1 2 5 2}
。
堆垛通常由两个步骤完成:
您的max_heap()
只执行堆积(无法完全理解您的实施),而不是创建最大堆。看来你正在使用&#34; siftUp&#34;具有O(n log n)时间复杂度的heapify版本,而&#34; siftDown&#34; heapify的版本只有O(n)时间复杂度
添加构建堆的过程,您的heapsort将使用正确的heapify操作。
//build a heap first!
for (i=0; i<size; i++){
push(heapDelete());
}