堆的基本操作

  • 堆(heap)也被称为优先队列(priority queue)。队列中允许的操作是先进先出(FIFO),在队尾插入元素,在队头取出元素。而堆也是一样,在堆底插入元素,在堆顶取出元素,但是堆中元素的排列不是按照到来的先后顺序,而是按照一定的优先顺序排列的。这个优先顺序可以是元素的大小或者其他规则。
  • 堆可以分为最大堆和最小堆。

        最大堆满足:(1)根节点为最大值;(2)父节点大于子节点。

        堆最小堆满足:(1)根节点为最小值;(2)父节点小于子节点。

  • 堆的基本操作:(1)取堆顶元素;(2)删除堆顶元素;(3)插入一个元素。
  • 堆的代码实现:
heap.h:
#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stddef.h>

#define HeapMaxSize 1024
typedef char HeapType;
typedef int(*Compare)(HeapType a,HeapType b);

typedef struct Heap{
    HeapType data[HeapMaxSize];
    size_t size;
    Compare cmp;
}Heap;

int Greater(HeapType a, HeapType b);
int Less(HeapType a,HeapType b);
void HeapInit(Heap* heap,Compare cmp);
void HeapDestroy(Heap* heap);
void HeapInsert(Heap* heap,HeapType value);
void AdjustUp(Heap* heap,size_t index);
void Swap(HeapType* a,HeapType* b);
void HeapPrintChar(Heap* heap,const char* msg);
int HeapRoot(Heap* heap,HeapType* value);
void HeapErase(Heap* heap);
void AdjustDown(Heap* heap,size_t index);
void HeapCreate(Heap* heap,HeapType array[],size_t size);
void HeapSort(HeapType array[],size_t size);
heap.c:
#include "heap.h"

int Greater(HeapType a,HeapType b){
    return a>b?1:0;
}

int Less(HeapType a,HeapType b){
    return a<b?1:0;
}

void HeapInit(Heap* heap,Compare cmp){
    //初始化时决定这个堆是大堆还是小堆
    heap->size = 0;
    heap->cmp = cmp;
    return;
}

void HeapDestroy(Heap* heap){
    heap->size = 0;
    heap->cmp = NULL;
    return;
}

void Swap(HeapType* a,HeapType* b){
    HeapType tmp = *a;
    *a = *b;
    *b = tmp;
    return;
}

void AdjustUp(Heap* heap,size_t index){
    if(heap == NULL)
        return;
    size_t child = index;
    size_t parent = (child-1)/2;
    while(child > 0){
        if(!heap->cmp(heap->data[parent],heap->data[child])){
            Swap(&heap->data[parent],&heap->data[child]);
        }
        else{
            break;
        }
        child = parent;
        parent = (child-1)/2;
    }
    return;
}

void HeapInsert(Heap* heap,HeapType value){
    if(heap == NULL)
        return;
    if(heap->size >= HeapMaxSize)
        return;
    heap->data[heap->size++] = value;
    AdjustUp(heap,heap->size-1);
    return;
}

void HeapPrintChar(Heap* heap,const char* msg){
    printf("[%s]\n",msg);
    size_t i = 0;
    for(;i < heap->size;i++){
        printf("[%c | %lu]  ",heap->data[i],i);
    }
    printf("\n");
}

int HeapRoot(Heap* heap,HeapType* value){
    if(heap == NULL)
        return 0;
    if(heap->size == 0)
        return 0;
    *value = heap->data[0];
    return 1;
}

void AdjustDown(Heap* heap,size_t index){
    if(heap == NULL)
        return;
    size_t parent = index;
    size_t child = 2*index+1;
    while(child < heap->size){
        if(child+1 < heap->size && heap->cmp(heap->data[child+1],heap->data[child])){
            child = child+1;
        }
        if(heap->cmp(heap->data[child],heap->data[parent])){
            Swap(&heap->data[child],&heap->data[parent]);
        }
        else{
            break;
        }
        parent = child;
        child = 2*parent+1;
    }
}

void HeapErase(Heap* heap){
    if(heap == NULL)
        return;
    if(heap->size == 0)
        return;
    Swap(&heap->data[0],&heap->data[heap->size-1]);
    --heap->size;
    AdjustDown(heap,0);
}

void HeapCreate(Heap* heap,HeapType array[],size_t size){
    if(heap == NULL)
        return;
    size_t i = 0;
    for(;i < size; i++){
        HeapInsert(heap,array[i]);
    }
    return;
}

void HeapSort(HeapType array[],size_t size){
    Heap heap;
    HeapInit(&heap,Greater);
    HeapCreate(&heap,array,size);
    while(heap.size > 0){
        HeapErase(&heap);
    }
    memcpy(array,heap.data,size*sizeof(HeapType));
    return;
}
test.c:
#include"heap.h"

#define PRINT_HEAD printf("\n============%s============\n",__FUNCTION__);

extern Greater(HeapType a,HeapType b);

void TestInit(){
    PRINT_HEAD;
    Heap heap;
    HeapInit(&heap,Greater);
    printf("size expect 0,actual %lu\n",heap.size);
}

void TestInsert(){
    PRINT_HEAD;
    Heap heap;
    HeapInit(&heap,Greater);
    HeapInsert(&heap,'a');
    HeapInsert(&heap,'d');
    HeapInsert(&heap,'c');
    HeapInsert(&heap,'b');
    HeapInsert(&heap,'f');
    HeapInsert(&heap,'e');
    HeapPrintChar(&heap,"插入六个元素");
    HeapDestroy(&heap);
    printf("size expect 0,actual %lu\n",heap.size);
}

void TestRoot(){
    PRINT_HEAD;
    Heap heap;
    HeapInit(&heap,Greater);
    HeapInsert(&heap,'a');
    HeapInsert(&heap,'d');
    HeapInsert(&heap,'c');
    HeapInsert(&heap,'b');
    HeapInsert(&heap,'f');
    HeapInsert(&heap,'e');
    HeapType value = 0;
    int ret = HeapRoot(&heap,&value);
    printf("ret expect 1,actual %d\n",ret);
    printf("value expect f,actual %c\n",value);
}

void TestErase(){
    PRINT_HEAD;
    Heap heap;
    HeapInit(&heap,Greater);
    HeapInsert(&heap,'a');
    HeapInsert(&heap,'d');
    HeapInsert(&heap,'c');
    HeapInsert(&heap,'b');
    HeapInsert(&heap,'f');
    HeapInsert(&heap,'e');
    HeapPrintChar(&heap,"插入六个元素");
    HeapErase(&heap);
    HeapPrintChar(&heap,"删除一个元素");
}

void TestCreate(){
    PRINT_HEAD;
    Heap heap;
    HeapInit(&heap,Greater);
    HeapType array[] = {'a','d','c','b','f','e'};
    size_t size = sizeof(array)/sizeof(array[0]);
    HeapCreate(&heap,array,size);
    HeapPrintChar(&heap,"创建堆");
}

void TestSort(){
    Heap heap;
    HeapType array[] = {'a','d','c','b','f','e'};
    size_t size = sizeof(array)/sizeof(array[0]);
    HeapSort(array,size);
    HeapPrintChar(&heap,"堆排序");
}

int main(){
    TestInit();
    TestInsert();
    TestRoot();
    TestErase();
    TestCreate();
    TestSort();
    return 0;
}

结果演示:




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值