将值插入最大二进制堆时出现问题

Posted

技术标签:

【中文标题】将值插入最大二进制堆时出现问题【英文标题】:Having problems while inserting values into a max binary heap 【发布时间】:2019-05-28 00:20:15 【问题描述】:

我使用 C 创建了一个二进制堆。这里是初始化堆和插入值的函数

int *heapArray; // pointer to array of elements in heap
int capacity = 0; // maximum possible size of min heap, initially set to 0
int heap_size; // Current number of elements in min heap
int d = 2;  //max number of children per node

int getParent(int i) //get the parent index of i

    return (i/d);


bool isFull() //check if heap is full

    if(heap_size == capacity)
        return true;
    if(heap_size < capacity)
        return false;


void initializeHeap(int cap) //initialize the heap

    heap_size = 0;
    capacity = cap;
    heapArray = (int*)malloc(cap*sizeof(int));


void insertValue(int x) //insert a value into the heap

    if(isFull()) //If heap is already full, double the heap size
    
        capacity = 2*capacity;
        heapArray = realloc(heapArray,capacity*sizeof(int));
    

    heap_size = heap_size + 1;
    heapArray[heap_size] = x; //insert new value into heap (not zero-indexed)
    maxHeapSwim(heap_size);


void maxHeapSwim(int k) //move value up the heap to maintain max-heap order

    while(k > 1 && heapArray[getParent(k)] < heapArray[k])
    
        swap(&heapArray[k],&heapArray[parent(k)]);
        k = parent(k);
    

然后在 main() 方法中,我尝试将值插入到堆中并打印出值:

int main()


  initializeHeap(1); //Set the heap capacity to 1

  insertValue(2);
  insertValue(3);
  insertValue(1);
  insertValue(6);
  insertValue(4);

  printf("\n");
  printf("%i", heapArray[1]);
  printf("\n");
  printf("%i", heapArray[2]);
  printf("\n");
  printf("%i", heapArray[3]);
  printf("\n");
  printf("%i", heapArray[4]);
  printf("\n");
  printf("%i", heapArray[5]);
  printf("\n");

  return 0;


由于这是一个最大堆,我希望输出如下所示:

6
4
1
2
3

但是,它看起来像这样:

6
4
1
0
3

我不明白。为什么2变成0?我觉得这与我如何将 insertValue() 函数中的堆大小加倍有关....可能是我使用 realloc 的方式。是不是我做错了什么?

要注意的另一件事是我的二进制堆不是零索引的。第一个值插入 heapArray[1],第二个值插入 heapArray[2],以此类推。

【问题讨论】:

不要忽略警告。 n 个元素的数组从 0 到 n-1。 @stark 我知道这一点。但是我见过很多例子,其中通过将数组的第 0 个索引保持为空并将第一个值放在索引 1 处来构建二进制堆。这就是我在这里尝试做的事情。 那么需要在数组中分配n+1个空格。 【参考方案1】:

您的代码第一部分的一些更改对我有用。

实现swap() 和一些小改动。

代码

#define false 0
#define true 1

int *heapArray; // pointer to array of elements in heap
int capacity = 0; // maximum possible size of min heap, initially set to 0
int heap_size; // Current number of elements in min heap
int d = 2;  //max number of children per node

int getParent(int i) //get the parent index of i

    return (i/d);


void maxHeapSwim(int k) //move value up the heap to maintain max-heap order

    while(k > 1 && heapArray[getParent(k)] < heapArray[k])
    
        //swap(&heapArray[k],&heapArray[parent(k)]);
        int x=heapArray[k];
        heapArray[k]=heapArray[getParent(k)];
        heapArray[getParent(k)]=x;
        k = getParent(k);
    


int  isFull() //check if heap is full

    if(heap_size == capacity)
        return true;
    if(heap_size < capacity)
        return false;


void initializeHeap(int cap) //initialize the heap

    heap_size = 0;
    capacity = cap;
    heapArray = (int*)malloc(cap*sizeof(int));


void insertValue(int x) //insert a value into the heap

    if(isFull()) //If heap is already full, double the heap size
    
        capacity = 2*capacity;
        heapArray = realloc(heapArray,capacity*sizeof(int));
    

    heap_size = heap_size + 1;
    heapArray[heap_size] = x; //insert new value into heap (not zero-indexed)
    maxHeapSwim(heap_size);





int main()
  

  initializeHeap(1); //Set the heap capacity to 1

  insertValue(2);
  insertValue(3);
  insertValue(1);
  insertValue(6);
  insertValue(4);

  printf("\n");
  printf("%i", heapArray[1]);
  printf("\n");
  printf("%i", heapArray[2]);
  printf("\n");
  printf("%i", heapArray[3]);
  printf("\n");
  printf("%i", heapArray[4]);
  printf("\n");
  printf("%i", heapArray[5]);
  printf("\n");

  return 0;

输出

./code 


6
4
1
2
3

【讨论】:

它没有用。我仍然得到输出 6,4,1,0,3 而不是 6,4,1,2,3 还是不行。您在我的代码中更改的唯一内容是 maxHeapSwim 函数以及 define false 0define true 1。我还缺少其他任何更改吗? 是的,我只更改maxHeapSwim(),但正如我在输出中显示的那样,它在我的终端上工作。 这是在线编译器上的代码输出:jdoodle.com/a/SPC 是的,但它仍然没有工作。我设法解决了这个问题。我稍后会发布它作为答案。【参考方案2】:

这对我有用:

void insertValue(int x)

    if(capacity < 10)
    
        capacity = 10;
        heapArray = (int*)realloc(heapArray,capacity*sizeof(int));
    
    if(heap_size >= capacity/2)
    
        capacity += 10;
        heapArray = (int*)realloc(heapArray,capacity*sizeof(int));
    

    heap_size = heap_size + 1;
    heapArray[heap_size] = x;
    maxHeapSwim(heap_size);

关键是要确保二进制堆永远不会满。

【讨论】:

以上是关于将值插入最大二进制堆时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

尝试将数据表批量插入 SQL Server 时出现 InvalidOperationException

Access 2007,VBA:将 BLOB 插入链接表时出现奇怪的错误

使用 Databricks 将十进制字段加载到 Redshift 表时出现 Avro 文件错误

链表:将值分配给节点的下一部分时出现分段错误错误

运行递归线性搜索时出现堆栈溢出错误

将记录插入 phpmyadmin 时出现 Asynctask 错误