C 最小堆结构中的哨兵控制循环
我对堆的定义如下: 文件:heap.hC 最小堆结构中的哨兵控制循环,c,heap,sentinel,C,Heap,Sentinel,我对堆的定义如下: 文件: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 <stdi
#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--;
}
find_value
具有sentinel功能(避免一次测试):
int find_值(int*v,int n,int x){
int i=0;
如果(v[n-1]==x)返回1;//x在最后一个位置
int last=v[n-1];//保存最后一个元素
v[n-1]=x;//在v中至少有一个x元素(test[ii如果您使代码更具可读性(停止在一行上放置多个逻辑操作),您可能会得到更多帮助。“如果”获取它自己的行,每行一个变量,不要在其他逻辑操作中使用+/--in等。代码行的减少并不是以复杂性为代价的改进。您可以忽略第一个if条件。剩余的代码在我看来不是不可读的。什么意思,“通过哨兵控制它”?您的意思是“如果其他变量为true,但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;
}
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;
}