构建Max_Heap并使用数组中的数据填充它

时间:2014-03-30 02:30:17

标签: c arrays sorting heap heapsort

我必须使用基于元素序列号的reheapUP函数构建maxheap,然后我需要根据元素的优先级编号打印它。 我的元素采用以下格式:

typedef struct customer
{
char  name[255];
int mileage;
int years;
int priority;
int serial;
} CUSTOMER;

到目前为止,我已经从文件中读取数据,并保存到结构数组中,并按序列号的降序排序。(我甚至不确定是否需要对数组进行排序插入堆之前)

1)现在我需要使用reheapUp函数从该数组构建一个堆。此函数应在树的底部插入一个元素,并递归地将其与堆中的父元素进行比较,并在需要时交换它们。我不知道如何实现这一点。

//#define LEFT(x) 2*x+1 // since we start with index 0
//#define RIGHT(x) 2*x+2

void reheapUp(struct customer* record, int idx)
{
int l = LEFT(idx);
int r = RIGHT(idx);
int largest;

   if( l <= heap_size(record) && record[l].serial > record[idx].serial)
       largest = l;
   else
       largest = idx;

   if(r <= heap_size(record) && record[r].serial > record[largest].serial)
      largest = r;

   if(largest != idx) {        // the thing here is that I need to swap all of the elements, not just their serials.
      int temp = record[idx].serial;
      record[idx].serial = record[largest].serial;
      record[largest].serial = temp;
      rehepUp(record, largest);
 }
}

void insertHeap(HEAP* heap, CUSTOMER* dataPtr)
{
heap->root->parent = NULL;
if (heap)
{
    heap->last = heap->last->priority + 1;
    heap->last->dataPtr->mileage = dataPtr->mileage;
    heap->last->dataPtr->priority = dataPtr->priority;
    heap->last->dataPtr->serial = dataPtr->serial;
    heap->last->dataPtr->years = dataPtr->years;
    strcpy(heap->last->dataPtr->name, dataPtr->name);
    reheapUp(last);
}

}

请帮我修复我的功能,这样我就可以从数组中构建一个maxHeap。此外,稍后我需要使用reheapDown并在执行此操作时打印数据。我也不知道我该怎么做。谢谢

我发现并试图为自己优化的另一个代码版本(程序崩溃): 这段代码最初用于一个整数数组,因为我的程序需要运行struct CUSTOMER,我试过修改它,但它没有多大帮助。有什么想法吗?

#define SIZE 15
//#define heap_size(x) (sizeof(x)/sizeof(x[0]))
int* TREE; // global variable used for printing the entire tree

int main(int argc, char *argv[])
 {
HEAP* heap;
struct customer record [SIZE];
int n = sizeof(record)/sizeof(int);
TREE = record;
int heapSize = SIZE;
int idx = 0;

idx = readFile(record);
heap = initHeap(heapSize);

calcSerial(record, idx);
sortArray(record, idx);
printTree();
buildHeap(record, n);
printTree();
return 0;
}

void printTree(void)
{
// lazy way to print the entire tree...
int* array = TREE;
printf("                        %3d\n ", array[0]);
printf("            %3d                     %3d\n", array[1], array[2]);
printf("      %3d         %3d         %3d         %3d\n", array[3], array[4], array[5], array[6]);
printf("   %3d   %3d   %3d   %3d   %3d   %3d   %3d   %3d\n", array[7], array[8], array[9], array[10], array[11], array[12], array[13], array[14]);
printf("%3d\n", array[15]);

printf("\n");
}

void buildHeap(struct customer* record, int n)
{
printf("buildHeap\n");
// changed starting condition
int i = n/2;
// changed from i-- to --i so we get to zero
while(i > 0) heapify(record, n,--i);
}

void heapify(struct customer* record, int n,  int i)
{
printf("heapify [%i] = %i\n", i, record[i]);
printTree();
// mark nodes initially as -1 to distinguish from "valid" zero
int childLeft = -1, childRight = -1;
int largest = i;

// changed the way we check for valid nodes:
if(2*i+1<n) childLeft = 2*i+1;
if(2*i + 2<n) childRight = 2*i + 2;

// see if any nodes are invalid now:
if(childLeft < 0 && childRight < 0) return;
if(childLeft < 0) childLeft = childRight;
if(childRight < 0) childRight = childLeft;

printf("child left [%i] = %i  child right [%i] = %i\n", childLeft, record[childLeft], childRight, record[childRight]);
if(record[childLeft].serial > record[i].serial) largest = childLeft;
if(record[childRight].serial > record[largest].serial) largest = childRight;
if(largest != i)
{
 swap(record, i,largest);
 heapify(record, n, largest);
 }
}

void swap(struct customer* record, int indexA, int indexB)
{
 CUSTOMER* temp;
 temp = (CUSTOMER*)(malloc(sizeof(CUSTOMER)));
 printf("swap [%i] %s with [%i] %s\n", indexA, record[indexA].name, indexB, record[indexB].name);

temp->mileage = record[indexA].mileage;
temp->years = record[indexA].years;
temp->serial = record[indexA].serial;
temp->priority = record[indexA].priority;
strcpy(temp->name, record[indexA].name);

record[indexA].mileage = record[indexB].mileage;
record[indexA].years = record[indexB].years;
record[indexA].serial = record[indexB].serial;
record[indexA].priority = record[indexB].priority;
strcpy(record[indexA].name, record[indexB].name);

record[indexB].mileage = temp->mileage;
record[indexB].years = temp->years;
record[indexB].serial = temp->serial;
record[indexB].priority = temp->priority;
strcpy(record[indexB].name, temp->name);
}

0 个答案:

没有答案