Binary heap sequential storage

Time:2020-11-28

Implementation of binary heap by array


Create three files: heaprarray. H, heaprarray. C, heapararraytest. C


heapArray.h
#ifndef HEAP_ARRAY_H_
#define HEAP_ARRAY_H_

#ifdef __GNUC__
	#define DEPRECATED __attribute__( (deprecated) )
#elif defined(_MSC_VER)
	#define DEPRECATED __declspec( deprecated )
#else
	#define DEPRECATED
#endif

#ifndef PTOI
	#define PTOI( p ) ((int32_t)(int64_t)(p))
#endif
#ifndef ITOP
	#define ITOP( i ) ((void *)(int64_t)(i))
#endif

#define ADT HeapArray

//Function: the process of comparison between a and B
//Parameters: A, B
//Return: a > B returns a positive number, a

heapArray.c
#include 
#include 
#include 
#include "heapArray.h"


//Function: print the error message and exit the program
//Parameters: expression (error judgment expression), message (error message to be printed)
//Return: none
//Note: only triggered when expression is true
#define ERROR_EXIT( expression, message )                                    \
if( (expression) ) {                                                         \
	fprintf( stderr, "\nerror location: file = %s, func = %s, line = %d.\n", \
	                       __FILE__, __func__, __LINE__ );                   \
	fprintf( stderr, "error  message: %s%s.\n\a",                            \
	                       (message) != NULL ? (message) : __func__,         \
		                   (message) != NULL ? "" : " function error" );     \
	exit( EXIT_FAILURE );                                                    \
}

//Function: two elements of array are exchanged
//Parameters: a (array first address), I (array subscript), J (array subscript)
//Return: none
//Note: macro without side effects, C99 standard: ා define f ({...})
#define SWAP( a, i, j ) ({            \
	int32_t i1i1i = (i), j1j1j = (j); \
	void *t1t1t = *((a) + i1i1i);     \
	*((a) + i1i1i) = *((a) + j1j1j);  \
	*((a) + j1j1j) = t1t1t;           \
})

#define ADT HeapArray


struct HeapArray {
	int32_t capacity;
	int32_t size;
	CompareFunc *cmp;
	void *array[0];
};


ADT *newHeapArray( int32_t capacity, CompareFunc *cmp ) {
	ADT *heap = NULL;

	ERROR_EXIT( !cmp, NULL );
	capacity = capacity < 0 ? 512 : capacity;
	heap = malloc( sizeof(*heap) + sizeof(heap->array[0]) * capacity );
	ERROR_EXIT( !heap, NULL );
	heap->capacity = capacity;
	heap->size = 0;
	heap->cmp = cmp;

	return heap;
}

void *addHeapArray( HeapArray *heap, void *data ) {
	int32_t i = 0;

	ERROR_EXIT( !heap || heap->size >= heap->capacity, NULL );
	i = heap->size++;
	heap->array[i] = data;

	for( int32_t p = (i - 1) / 2; heap->cmp( heap->array[i], heap->array[p] ) < 0; p = (i - 1) / 2 ) {
		// i: index, p: parent.
		SWAP( heap->array, p, i );
		i = p;
	}

	return data;
}

void *addHeadHeapArray( HeapArray *heap, void *data ) {
	return NULL;
}

void *pollHeapArray( HeapArray *heap ) {
	int32_t i = 0;

	ERROR_EXIT( !heap || heap->size < 1, NULL );
	Swap (heap > array, 0, heap > size - 1); // swap the top and bottom of the heap
	--heap->size;
	for( int32_ T l = I * 2 + 1; l < heap > size; L = I * 2 + 1) {// adjust from top to bottom of heap
		// l: left child, r: right child, m: maximum or minimum.
		int32_t r = l + 1, m = l;
		if( r < heap->size && heap->cmp( heap->array[r], heap->array[l] ) < 0 ) {
			m = r;
		}
		if( heap->cmp( heap->array[i], heap->array[m] ) <= 0 ) {
			break;
		}
		SWAP( heap->array, m, i );
		i = m;
	}

	return heap->array[heap->size];
}

void *pollTailHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap || heap->size < 1, NULL );

	return heap->array[--heap->size];
}

void *peekHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap || heap->size < 1, NULL );

	return heap->array[0];
}

void *peekTailHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap || heap->size < 1, NULL );

	return heap->array[heap->size - 1];
}

int existHeapArray( HeapArray *heap, void *data ) {
	ERROR_EXIT( !heap, NULL );

	for( int32_t i = 0; i < heap->size; ++i ) {
		if( !heap->cmp( heap->array[i], data ) ) {
			return 1;
		}
	}

	return 0;
}

int32_t findHeapArray( HeapArray *heap, void *data ) {
	ERROR_EXIT( !heap, NULL );
	for( int32_t i = 0; i < heap->size; ++i ) {
		if( !heap->cmp( heap->array[i], data ) ) {
			return i;
		}
	}

	return -1;
}

int32_t findTailHeapArray( HeapArray *heap, void *data ) {
	ERROR_EXIT( !heap, NULL );
	for( int32_t i = heap->size - 1; i >= 0; --i ) {
		if( !heap->cmp( heap->array[i], data ) ) {
			return i;
		}
	}

	return -1;
}

int32_t sizeHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap, NULL );

	return heap->size;
}

int emptyHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap, NULL );

	return heap->size < 1;
}

int fullHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap, NULL );

	return heap->size >= heap->capacity;
}

int32_t capacityHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap, NULL );

	return heap->capacity;
}

void clearHeapArray( HeapArray *heap ) {
	ERROR_EXIT( !heap, NULL );

	heap->size = 0;
}

void delHeapArray( HeapArray **heap ) {
	ERROR_EXIT( !heap, NULL );
	free( *heap );
	*heap = NULL;
}

heapArrayTest.c
#include 
#include 
#include 
#include 
#include "heapArray.h"


//A > B returns a positive number