转载:http://62.234.110.144:8991/2019/07/20/c%E5%AE%9E%E7%8E%B0%E5%B0%8F%E9%A1%B6%E5%A0%86-%E5%9F%BA%E4%BA%8E%E6%95%B0%E6%8D%AE%E6%B5%81%E4%B8%AD%E6%89%BE%E5%87%BA%E4%B8%80%E6%AE%B5%E6%95%B0%E6%8D%AE%E7%9A%84%E6%9C%80%E5%B0%8F%E5%80%BC/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned int
#define BASE 0x10000000
#define HEAP_OK (BASE + 0x01)
#define CALLOC_FAILED (BASE + 0x02)
#define DATA_CONVERT_OK (BASE + 0x03)
#define DATA_CONVERT_FAILED (BASE + 0x04)
#define SWAP(array,i,j) do{ \
assert(array); \
array[i] ^= array[j]; \
array[j] ^= array[i]; \
array[i] ^= array[j]; \
}while(0)
#define MAXHEAPNAME "max heap sort"
#define MINHEAPNAME "min heap sort"
#define ISMIN(a,b) ((a) < (b) ? (1):(0))
//#define heapAjust(...) heapAlloc((_heapType){__VA_ARGS__})
//堆结构
typedef struct __heap{
uint32_t heapSize;
uint32_t array[0];
}_heap;
//typedef struct __heapType{
// uint8_t *name;
// (void *func)(_heap *,uint32_t,uint8_t);
//}_heapType;
/** @brief heapAjust
* 堆调整
* @param heap - 申请到的堆指针
* @param id - 当前调整pos
* @param mode - 大堆:1,小堆:0
* @return
*
*/
void heapAjust(_heap *heap,uint32_t id,uint8_t mode)
{
uint32_t leftChild,rightChild,utilId;
leftChild = 2*id + 1;
rightChild = 2*id + 2;
utilId = ((ISMIN(leftChild , heap->heapSize)) \
&& ((mode)|ISMIN(heap->array[leftChild],heap->array[id]))) ? \
leftChild : \
id;
utilId = (ISMIN(rightChild , heap->heapSize) \
&& ((mode)|ISMIN(heap->array[rightChild],heap->array[utilId]))) ? \
rightChild : \
utilId;
if(utilId != id)
{
SWAP(heap->array,utilId,id);
heapAjust(heap,utilId,mode);
}
}
/** @brief createHeap
* 创建堆
* @param heap - 申请到的堆指针
* @param name - 堆名字
* @return
*
*/
void createHeap(_heap *heap , const uint8_t *name)
{
assert(heap && name);
int i = 0,size = heap->heapSize / 2;
for (i = size;i >= 0;heapAjust(heap,i,(strcmp(name,MINHEAPNAME) == 0 ? 0:1)),i--);
}
/** @brief getDataToTree
* 将数据流中的数据放入完全二叉树,该处只定义了一个数组(实际过程中可采用管道、消息队列进行数据传递)
* @param heap - 堆指针实例
* @return heap - 动态增减后的堆指针
*
*/
_heap *getDataToTree(_heap *heap)
{
int i = 0;
uint32_t array[6] = {16 ,11, 24, 17, 18, 41};
heap = (_heap *)calloc(1,sizeof(_heap));
for (i =0;i<6;i++){
heap = realloc(heap,sizeof(uint32_t) * (++(heap->heapSize) + 1));
if(heap == NULL){
//printf("realloc failed!\n");
goto fail;
}
printf("end.\n");
heap->array[heap->heapSize-1] = array[i];
}
//heap = realloc(heap,sizeof(uint32_t) * (--heap->heapSize+1));
return heap;
fail:
return NULL;
}
int main()
{
int i = 0,value = 0;
int ret = 0;
_heap *heapInstance;
heapInstance = getDataToTree(heapInstance);
if(heapInstance == NULL)
goto fail;
printf("the source data:");
for(i = 0;i < heapInstance->heapSize;i++)
{
if(i % 16 == 0)
printf("\n");
printf("%02d ",heapInstance->array[i]);
}
printf("\n");
createHeap(heapInstance,MINHEAPNAME);
printf("the minheap:");
for(i = 0; i < heapInstance->heapSize;i++)
{
if(i % 16 == 0)
printf("\n");
printf("%02d ",heapInstance->array[i]);
}
printf("\n");
createHeap(heapInstance,MAXHEAPNAME);
printf("the maxheap:");
for(i = 0;i < heapInstance->heapSize;i++)
{
if(i % 16 == 0)
printf("\n");
printf("%02d ",heapInstance->array[i]);
}
printf("\n");
free(heapInstance);
fail:
return 0;
}
share$ gcc heap.c -o heap
share$ ./heap
the source data:
16 11 24 17 18 41
the minheap:
11 16 24 17 18 41
the maxheap:
41 18 24 17 16 11