我的数组的值以意想不到的方式发生变化

时间:2014-03-28 19:57:53

标签: c arrays heapsort

#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*/
}

2 个答案:

答案 0 :(得分:1)

我已经使用了您的代码,需要注意的一点是parentleft childright 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交换到正确的位置,交换会中断堆,然后堆积其余的堆。

您的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());
}