堆的应用 ---- 1.优先级队列 2.海量TOPK问题 3.堆排序

1.优先级队列
用堆实现队列

typedef struct PriorityQueue
{
    Heap hp;
}PriorityQueue;

void InitPriorityQueue(PriorityQueue* q)//初始化
{
    assert(q);
    InitHeap(&(q->hp));
}
void PushPriorityQueue(PriorityQueue* q, HPDataType data)//入队
{
    assert(q);
    InsertHeap(&q->hp,data);
}
void PopPriorityQueue(PriorityQueue* q)//出队
{
    assert(q);
    RemoveHeap(&q->hp);
}
HPDataType TopPriorityQueue(PriorityQueue* q)//取堆顶
{
    assert(q);
    return TopHeap(&q->hp);
}
int SizePriorityQueue(PriorityQueue* q)//大小
{
    assert(q);
    return SizeHeap(&q->hp);
}
int EmptyPriorityQueue(PriorityQueue* q)//判空
{
    assert(q);
    return EmptyHeap(&q->hp);
}

2.100亿个数中找出最大的前K个数(海量数据TOP K问题)
由于100亿这个数据太大,所以不适宜用冒泡或者其他排序的方法实习,这里用堆实现比较好
思路:
1.获取前K个元素 —– 用前K个元素建立堆
2.用剩余的元素依次与堆顶元素比较 若比堆顶元素小—–>丢弃
若比堆顶元素大—–>用该元素替换堆顶元素—->将堆顶元素进行向下调整

void HeapAdjust(Heap* hp)
{
    assert(hp);
    int end = hp->_size;
    hp->_size--;
    if (EmptyHeap(hp))
        return;
    while(hp->_size > 0)
    {
        Swap(&hp->_hp[0], &hp->_hp[hp->_size--]);
        AdjustDown(hp, 0);
    }

    hp->_size = end;
}
void HeapSort(int* array, int size)//堆排序
{
    Heap hp;
    assert(array);
    CreatHeap(&hp, array, size, Less);
    HeapAdjust(&hp);
}

3.堆排序
思路:
与堆删除的方法一样,让最顶上的元素与最后一个元素进行替换,然后让除去最后一个元素的其他元素进行再次排序,重复上述过程直到所有元素遍历一遍。

void TopK(int* array, int size,int k)//海量数据TOP K
{
    Heap hp;
    int i = 0;
    assert(array);
    InitHeap(&hp);
    hp._compare = Less;
    for (; i < k; i++)
    {
        InsertHeap(&hp, array[i]);
    }
    while (i < size)
    {
        if (TopHeap(&hp) < array[i])
        {
            Swap(&hp._hp[0], &array[i++]);
            AdjustDown(&hp, 0);
        }
    }
}

上述的代码中有用到关于堆的基本操作,在上一篇文章中有,可以借鉴参考。

猜你喜欢

转载自blog.csdn.net/qq_39032310/article/details/82313303