堆及堆的应用

Heap.h

#ifndef __HEAP_H__
#define __HEAP_H__

typedef int HPDataType;
typedef struct Heap
{
   HPDataType* _hp;
   int _capacity;
   int _size;

}Heap;


typedef struct PriorityQueue 
{ 
    Heap hp; 
}PriorityQueue; 

void CreatHeap(Heap* hp, int* array, int size);//创建堆
void InitHeap(Heap* hp); // 初始化堆 
void PrintHeap(Heap hp);//打印堆
void InsertHeap(Heap* hp, HPDataType data);//插入数据
void RemoveHeap(Heap* hp);//删除堆顶元素
int SizeHeap(Heap*hp);//堆大小
int EmptyHeap(Heap* hp);//判空
HPDataType TopHeap(Heap* hp);//找出堆顶元素
void AdjustDown(Heap* hp, int parent);//向下调整
void AdjustUp(Heap* hp, int child);//向上调整
void _CheakCapacity(Heap* hp);//扩容
void DestroyHeap(Heap* hp); // 销毁堆 
int Less(HPDataType left, HPDataType right); // 小于比较 
int Greater(HPDataType left, HPDataType right); // 大于比较 
void InitPriorityQueue(PriorityQueue* q); 
void PushPriorityQueue(PriorityQueue* q, HPDataType data); 
void PopPriorityQueue(PriorityQueue* q); 
int TopPriorityQueue(PriorityQueue* q); 
int SizePriorityQueue(PriorityQueue* q); 
int EmptyPriorityQueue(PriorityQueue* q); 
void Topk(Heap* q, int k);//海量数据中的topk问题
void HeapSort(Heap *q);//堆排序

Heap.c

#include "Heap.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>


void CreatHeap(Heap* hp, int* array, int size)
{
    int i = 0;
    int root = (size-2)/2;
    assert(hp);
    hp->_hp = (HPDataType*)malloc(sizeof(HPDataType)*size);
    if(NULL == hp->_hp)
    {
        assert(hp);
        return;
    }

    hp->_capacity = size;
    hp->_size = size;
    for(i=0;i<size;i++)
    {
        hp->_hp[i] = array[i];
    }
    for(i=root;i>=0;i--)
    {
      AdjustDown(hp,i);
    }

}
void InitHeap(Heap* hp)
{
    assert(hp);
    hp->_hp = (HPDataType*)malloc(sizeof(HPDataType));
    if(NULL == hp->_hp)
    {
       return;
    }
    hp->_capacity = 1;
    hp->_size = 0;

}
void PrintHeap(Heap hp)
{
    int i = 0;
    for(i=0;i< hp._size;i++)
      {
        printf("%d ", hp._hp[i]);
      }

}
void Swap(int* left,int* right)
{
    int temp = 0;
     temp = *left;
     *left = *right;
     *right = temp;

}

int Greater(HPDataType left, HPDataType right)
{
    if (left > right)
        return 1;
    return 0;
}


int Less(HPDataType left, HPDataType right)
{
    if (left < right)
        return 1;
    return 0;
}
void AdjustDown(Heap* hp, int parent)
{
   int child = 2*parent+1;
   assert(hp);
   while(child < hp->_size)
   {
       if(Greater(hp->_hp[child],hp->_hp[child+1]) && (child+1) < hp->_size)
       {
         child = child+1;
       } 
       if(Greater(hp->_hp[parent] , hp->_hp[child]))
           {
            Swap(&hp->_hp[parent],&hp->_hp[child]);
             parent = child;
             child = 2*parent+1;
           }
       else
           return;

   }

}
void AdjustUp(Heap* hp, int child)
{
   int parent = (child-1)/2;
   assert(hp);
   while(child != 0)
   {
       if(Greater(hp->_hp[parent],hp->_hp[child]))
       {
           Swap(&hp->_hp[parent],&hp->_hp[child]);
               child = parent;
               parent = (child-1)/2;

       }
       else
           return;
   }

}
void _CheakCapacity(Heap* hp)
{
    int i = 0;
    assert(hp);
    if(hp->_capacity == hp->_size)
   {
       hp->_hp = (HPDataType*)realloc(hp->_hp,sizeof(HPDataType)*(hp->_capacity)*2); 
       if(NULL == hp->_hp)
       {

        return;
       }
       hp->_capacity = 2*hp->_capacity;
   }


}
void InsertHeap(Heap* hp, HPDataType data)
{
    int i = 0;
   assert(hp);
   _CheakCapacity(hp);
   hp->_hp[hp->_size++] = data;
   AdjustUp(hp,hp->_size-1);

}
int EmptyHeap(Heap* hp)
{
    assert(hp);
    if (hp->_size == 0)
        return 1;

    return 0;

}
void RemoveHeap(Heap* hp)
{
    assert(hp);

    //判断堆是否为空
    if (EmptyHeap(hp))
        return;

    //先将堆顶元素和堆尾元素交换,并删除堆尾元素
    Swap(&(hp->_hp[0]), &hp->_hp[hp->_size - 1]);
    hp->_size--;

    //用向下调整法调整队列
    AdjustDown(hp, 0);


}
int SizeHeap(Heap*hp)
{
    assert(hp);
    return hp->_size;
}
HPDataType TopHeap(Heap* hp)
{
    assert(hp);

    if (hp->_size == 0)
    {
        return 0;
    }

    return hp->_hp[0];
}
void DestroyHeap(Heap* hp)
{
    assert(hp);

    hp->_size = 0;
    hp->_capacity = 0;
    free(hp->_hp);
    hp->_hp = NULL;

    return;

}
///优先级队列
void InitPriorityQueue(PriorityQueue* q)
{
    InitHeap(&q->hp);
}
void PushPriorityQueue(PriorityQueue* q, HPDataType data)
{
    InsertHeap(&q->hp, data);

}
void PopPriorityQueue(PriorityQueue* q)
{
    int i = 0;
    int root = (q->hp._size-2)/2;  
    RemoveHeap(&q->hp); 
    for(i=root;i>=0;i--)
    {
      AdjustDown(&q->hp,i);
    }

}
int TopPriorityQueue(PriorityQueue* q) 
{

    return TopHeap(&q->hp); 
}
int SizePriorityQueue(PriorityQueue* q)
{
    return SizeHeap(&q->hp);
}
int EmptyPriorityQueue(PriorityQueue* q)
{
    return EmptyHeap(&q->hp);
}
//topk问题
void Topk(Heap* q, int k)
{
    int i = 0;
    int j = 0;
    assert(q);
    q->_hp = (HPDataType*)malloc(sizeof(HPDataType)*k);
    if(q->_hp == NULL)
    {
      assert(0);
      return;
    }

    //首先取前K个数,用着K个数来创建一个小堆
    for(i=0;i<k;i++)
    {
      int temp = rand()%10000;
      q->_hp[i] = temp;
    }

    q->_size = k;
    for(i=(k-2)/2;i>=0;i--)
    {
        AdjustDown(q,i);
    }
    //然后,一个一个的取数组内剩下的数,取出的数与堆顶的元素比较,如果比堆顶的元素大的话,就用取出的元素
    //代替堆顶的元素,代替之后再进行向下的调整,使堆重新满足小堆的特性,然后再从数组内取数据,重复上述操作,直到所有的数组为空时
      for(j=k;j<10000;j++)
    {
      int temp = rand()%10000;
      if(temp > q->_hp[0])
      {
          Swap(&temp,&q->_hp[0]);
          AdjustDown(q,0);

      }

    }
    PrintHeap(*q);
}
//堆排序
//如果是降序的话, 建一个小堆
//然后,先将小堆的堆顶的值与堆底的值交换,这样最小值就到了堆底,然后调整的元素个数-1,向下法调整交换后的堆
//调整好的堆最小值又在堆顶,然后再次与最后的元素交换,直到元素个数为0时停止
void HeapSort(Heap *q)
{
    int  i = q->_size;
    assert(q);
    i = q->_size;
    while(i)
    {
        //交换堆底和堆顶的元素
        Swap(&q->_hp[i-1], &q->_hp[0]);
        //把最小值放到堆底之后,元素个数-1;
        --i;
        //调整剩下的几个元素的堆
        AdjustDown(q,0);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值