我的堆定义如下:
文件:heap.h
#ifndef __HEAP__
#define __HEAP__
typedef struct heap heap;
heap* heap_new();
void heap_delete(heap* h);
void heap_insert(heap* h, int x);
void heap_delete_last(heap* h);
#endif
文件:heap.c
#include "heap.h"
#include <stdio.h>
#include <stdlib.h>
#ifndef MIN_SIZE
#define MIN_SIZE 4
#endif
struct heap {
int* v;
int n;
int size;
};
// ---------------------------------------------------------------------
// expand
// ---------------------------------------------------------------------
// expand heap size by 50%
static void expand(heap* h) {
h->size += h->size/2;
h->v = realloc(h->v, h->size*sizeof(int));
}
// ---------------------------------------------------------------------
// heap_new
// ---------------------------------------------------------------------
// create new empty heap object
heap* heap_new() {
heap* h = malloc(sizeof(heap));
h->size = MIN_SIZE;
h->v = malloc(h->size*sizeof(int));
h->n = 0;
return h;
}
// ---------------------------------------------------------------------
// heap_delete
// ---------------------------------------------------------------------
// delete heap object
void heap_delete(heap* h) {
free(h->v);
free(h);
}
// ---------------------------------------------------------------------
// heap_dump
// ---------------------------------------------------------------------
// dump heap content to stdio
void heap_dump(heap* h) {
int i;
for (i=0; i<=h->n; i++)
printf("[%d] %d\n", i, h->v[i]);
}
// ---------------------------------------------------------------------
// heap_check
// ---------------------------------------------------------------------
// test heap correctness
int heap_check(heap* h) {
int i;
for (i=1; i<=h->n; i++)
if ( i > 1 && h->v[i] < h->v[i/2] ) return 0;
if (2*i <= h->n && h->v[i] > h->v[2*i] ) return 0;
if (2*i+1 <= h->n && h->v[i] > h->v[2*i+1]) return 0;
return 1;
}
// ---------------------------------------------------------------------
// heap_insert
// ---------------------------------------------------------------------
// insert key into heap
void heap_insert(heap* h, int x){
if (++h->n == h->size) expand(h);
int *v = h->v;
unsigned long c = h->n, p = c >> 1;
while (p > 0 && v[p] > x) {
v[c] = v[p];
c = p;
p >>= 1;
}
v[c] = x;
}
// ---------------------------------------------------------------------
// heap_delete_last
// ---------------------------------------------------------------------
// remove last heap element
void heap_delete_last(heap* h) {
if (h->n > 0) h->n--;
}
我的问题非常简单。将注意力集中在heap_insert
函数上:有一个包含两个测试p > 0 && v[p] > x
的循环。考虑到这个循环,有没有办法用哨兵控制它并避免第二次测试?我从来没有遇到过这样的情况,无法猜出哨兵使用的是什么样的。提前谢谢。
我举一个哨兵控制循环的例子:
/*Returns 0 if x doesn't exist in v, 1 otherwise */
int find_value(int *v, int n, int x) {
int i;
//loop with 2 tests
for (i=0; i<n; i++)
if (v[i]==x) return 1;
return 0;
}
带有哨兵的 find_value
功能(避免一次测试):
int find_value(int *v, int n, int x) {
int i=0;
if(v[n-1] == x) return 1; //x is in the last spot
int last = v[n-1]; //save last element
v[n-1] = x; //one x element in v at least (test [i<n] id unnecessary)
while(v[i++] != x);
v[n-1] = last;
return i < n-1;
}