堆和堆的应用

堆的实现:

#include <malloc.h>
#include <assert.h>

typedef int DataType;
//函数指针--创建大堆或小堆
typedef int (*Comapra)(DataType,DataType);  

typedef struct heap
{
    DataType *_array;
    int _size;
    int _capycity;
    Comapra _com;
}heap;
  1. 实现堆的以下接口:
    // 创建堆
void create_hp(heap* head,int arr[],int size)
{
    DataType* tmp=NULL;
    int i=0;
    if(NULL==head)
        return;
    //申请空间
    checkcapycity(head,size);
    //赋值
    for(;i<size;i++)
    {
        head->_array[i]=arr[i];
    }
    head->_size=size;
    //堆调整
    i=(size-2)>>1;   //找到最后一个非叶节点的下标
    for (;i>=0;i--)
    {
        _adjust_up(head->_array,i,size,head->_com);
    }
}

// 在堆中插入值为data的元素

void insert_heap(heap* head,DataType data)
{
    int i=0;
    int size;
    if(NULL == head)
        return;
    size=++head->_size;
    checkcapycity(head,size);
    head->_array[size-1]=data;
    i=((size-2)>>1);   //找到最后一个非叶节点的下标
    for (;i>=0;i--)
    {
        _adjust_up(head->_array,i,size,head->_com);
    }
}

// 获取堆顶元素

DataType top_heap(heap* head)
{
    assert(head);
    return head->_array[0];
}

// 检测一个堆是否为空堆

int IsHeap_Empty(heap* head)
{
    if(NULL==head)
        return 0;
    return 0==head->_size;
}

// 获取堆中元素的个数

int Heap_size(heap* head)
{
    assert(head);
    return head->_size;
}

// 删除堆顶元素

void delet_heap(heap* head)
{
    int i;
    int size=head->_size;
    if(NULL == head)
        return;
    //用最后一个元素替换堆顶
    head->_array[0]=head->_array[size-1];
    head->_size--;
    //堆调整
    i=(size-2)>>1;   //找到最后一个非叶节点的下标
    for (;i>=0;i--)
    {
        _adjust_up(head->_array,i,size,head->_com);
    }
}

// 销毁堆

void destroy_heap(heap* head)
{
    assert(head);
    head->_size=0;
    head->_capycity=0;
    free(head->_array);
    head->_array=NULL;
}

对堆进行优化,一份代码既可以创建最大堆也可以创建最小堆
// 用于元素比较的比较器
//创小堆

int less(DataType a1,DataType a2)
{
    return a1>a2?1:0;
}

//创大堆

int greater(DataType a1,DataType a2)
{
    return a1<a2?1:0;
}

堆的应用之优先级队列,用堆封装优先级队列

#include "priorityQueue.h"

//初始化

void Init_priQueue(priQueue* head)
{
    Init_heap(&(head->hp),head->hp._com);
}

//创建优先级队列

void create_priQueue(priQueue* head,int arr[],int size)
{
    create_hp(&(head->hp),arr,size);
}

//插入元素

{
    insert_heap(&(head->hp),data);
}

//删除优先级最高的元素

{
    delet_heap(&(head->hp));
}

//获取优先级最高的元素

{
    return top_heap(&(head->hp));
}

//销毁优先级队列

{
    destroy_heap(&(head->hp));
}

//获取队列的size

{
    assert(head);
    return head->hp._size;
}

// 检测优先级队列是否为空

{
    assert(head);
    return 0==head->hp._size;
}

用堆的思想实现堆排序,给出代码实现

//堆排序
//升序--大堆
//降序--小堆
void heap_sort(int arr[],int size,Comapra com)
{
    heap Hp;
    int i=size;
    int j=0;
    Init_heap(&Hp,com);
    create_hp(&Hp,arr,size);
    for (;i>0;i--)
    {
        swap(&(Hp._array[0]),&(Hp._array[i-1]));
        //堆调整
        size--;        //每交换一次,将最后一个元素“屏蔽”
        j=(size-2)>>1;   //找到最后一个非叶节点的下标
        for (;j>=0;j--)
        {
            _adjust_up(Hp._array,j,size,com);
        }
    }
}
//交换
void swap(DataType* arr1,DataType* arr2)
{
    DataType tmp=*arr1;
    *arr1=*arr2;
    *arr2=tmp;
}
//堆调整--向上
void _adjust_up(DataType* arr,int n,int size,Comapra com)
{
    int parent=n;
    int child=2*n+1;
    while (child)
    {
        //找左右孩子中较大或较小的下标--child
        if(((child+1)<size) && com(arr[child],arr[child+1]))
            child+=1;
        //交换节点
        if(com(arr[parent],arr[child]))
            swap(&(arr[parent]),&(arr[child])); 
        child=parent;
        parent=((parent-1)>>1);
    }

}

用堆解决top-K问题,给出代码实现

//top-k问题
//需创建小堆
void heap_top_k(int arr[],int k,int size)
{
    heap Hp1;
    int i=0;
    Init_heap(&Hp1,less);
    //先将数组的前k个元素入堆
    create_hp(&Hp1,arr,k);
    //将N-K个元素与堆顶比较
    while (k<size)
    {
        int top=top_heap(&Hp1);
        //如果比堆顶大,就入堆--插入
        if(arr[k]>top)
        {
            delet_heap(&Hp1);
            insert_heap(&Hp1,arr[k]);
        }
        k++;
    }
    //打印
    for(;i<Hp1._size;i++)
    {
        printf("%d ",Hp1._array[i]);
    }
    printf("\n");
}

猜你喜欢

转载自blog.csdn.net/qq_33279168/article/details/80325287
今日推荐