使用堆函数时出现“找不到标识符”错误

问题描述 投票:0回答:1
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct{

    void** heapAry;    //
    int last;    //
    int size;    //
    int (*compare) (void* argu1, void* argu2);    // compare argumentations

    int maxSize; //

} HEAP;     //stuct HEAP

int compare(void *a, void *b)  {  

    if (a < b)   
        return -1;     // (return minus if former smaller)

    if (a > b)         // (return plus if former smaller)
        return 1;       
    else
        return 0;          // (return zero if former smaller)
}

HEAP* heapCreate (int maxSize)
{
    HEAP* heap = (HEAP*)malloc(sizeof (HEAP));    //creating heap
    if (!heap)
        return NULL;
    heap->last = -1;     // start of last; pre-existing
    heap->size = 0;      // start of size is zero
    // Force heap size to power of 2 -1
    heap->maxSize = (int) pow(2, ceil(log((double)maxSize)/log(2.0))) - 1;      
    heap->heapAry = (void**)calloc(heap->maxSize, sizeof(void*));
    return heap;
}    // createHeap

bool heapInsert (HEAP* heap, void* dataPtr)
{
    if (heap->size >= heap->maxSize)    // size cannot be bigger thant maxsize
        return false;
    ++(heap->last);    // increment last if insertion is true
    ++(heap->size);    // increment size if insertion is true
    heap->heapAry[heap->last] = dataPtr;    // The data lies in last of heap
    _reheapUp (heap, heap->last);    // And arrange the data in order of heap
    return true;
}

void _reheapUp (HEAP* heap, int childLoc)
{
    int parent = 0;
    void** heapAry = NULL;
    void* hold = NULL;
    if (childLoc){ // if not at root of heap -- index 0
        heapAry = heap->heapAry;
        parent = (childLoc - 1)/ 2;
        if (heap->compare(heapAry[childLoc], heapAry[parent]) > 0) {
            // child is greater than parent -- swap
            hold = heapAry[parent];
            heapAry[parent] = heapAry[childLoc];
            heapAry[childLoc] = hold;
            _reheapUp (heap, parent);
        } // if heap[]
    } // if newNode

}

bool heapDelete (HEAP* heap, void** dataOutPtr)
{
  if (heap->size == 0) // heap empty
    return false;
    *dataOutPtr = heap->heapAry[0];
  heap->heapAry[0] = heap->heapAry[heap->last];
  (heap->last)--;
  (heap->size)--;
  _reheapDown (heap, 0);
  return true;
}

void _reheapDown (HEAP* heap, int root)
{
  void* hold = NULL;
  void* leftData = NULL;
  void* rightData = NULL;
  int largeLoc = 0;
  int last = 0;
  last = heap->last;
  if ((root * 2 + 1) <= last){ 
    leftData = heap->heapAry[root * 2 + 1];
    if ((root * 2 + 2) <= last) // right subtree
      rightData = heap->heapAry[root * 2 + 2];
    else
      rightData = NULL;
    // Determine which child is larger
   if ((!rightData) ||
    heap->compare (leftData, rightData) > 0){
    largeLoc = root * 2 + 1;
   } else { // if no right key or leftKey greater
      largeLoc = root * 2 + 2;
     } // else
  // Test if root > larger subtree
  if (heap->compare (heap->heapAry[root],
    heap->heapAry[largeLoc]) < 0){
    // parent < children
    hold = heap->heapAry[root]; 
    heap->heapAry[root] = heap->heapAry[largeLoc];
    heap->heapAry[largeLoc] = hold;
    _reheapDown (heap, largeLoc);
  } // if root <
 } // if root

} // reheapDown

void* selectK(HEAP *heap, int k){

    if(k>heap->size)

    return false; // k shouldnt be larger than size

heap->size = heap->last+1;
for(int i=0; i<k; i++){
    void * temp =  heap-> heapAry[0];
    heapDelete(heap, heap->heapAry);
    temp = heap->heapAry[heap->last + 1];

}

void * holdout =  heap->heapAry[heap->last];
  while(heap->last<heap->size){

    heap->last++;
    _reheapUp(heap, heap->last);    

  }

  return holdout;

}

int main(){

  HEAP * heap = heapCreate(256);
  heapInsert(heap, (int*)1);
  heapInsert(heap, (int*)2);
  heapInsert(heap, (int*)3);
  heapInsert(heap, (int*)4);
  heapInsert(heap, (int*)5);
  int *x = (int*) selectK(heap, 3);

  printf("%d", *x); //print

}

从上面的源码中,我调试了但发现两个错误'_reheapUp':找不到标识符,'_reheapDown':找不到标识符。正如我猜测的那样,源代码缺乏连接性。怎么可能改变堆函数呢?我不知道该怎么办,这只是在我的书上,没有意义

c heap
1个回答
0
投票

您在声明 _reheapUp 和 _reheapDown 之前调用它们。最简单的做法是将它们的定义移至使用之前。

或者,您可以在使用函数之前添加前向声明。只是函数签名。

void _reheapUp (HEAP* heap, int childLoc);
void _reheapDown (HEAP* heap, int root);
© www.soinside.com 2019 - 2024. All rights reserved.