堆的应用--优先级队列和堆排

优先级队列:

就是队列中的元素是有优先级的,比如将优先级最高的放在队头,最低的放在队尾,那么在对队列进行操作时,如,出队列,只能先出优先级最高的,入队列,也要根据元素的优先级,将其放在对应的优先级处。优先级队列的本质就是队列里面封装了堆,具体代码如下,下面代码用到的堆可参考:
https://blog.csdn.net/virgofarm/article/details/80309534

PriorityQueue.h

#pragma once

#include "Heap.h"


//优先级队列就是封装堆
typedef struct PriorityQueue
{
    Heap _hp;

}PriorityQueue, *PQueue;


//队列初始化
void PriorityQueueInit(PQueue q);

//入队列
void PriorityQueuePush(PQueue q, DataType data);

//出队列
void PriorityQueuePop(PQueue q);

//查看队头元素
DataType PriorityQueueFront(PQueue q);

//查看队尾元素
DataType PriorityQueueBack(PQueue q);

//查看元素个数
int PriorityQueueSize(PQueue q);

//队列判空
int PriorityQueueFront(PQueue q);

//销毁队列
void PriorityQueueDestory(PQueue q);

PriorityQueue.c

#include "PriorityQueue.h"

//队列初始化
void PriorityQueueInit(PQueue q)
{
    assert(q);

    HeapInit(&(q->_hp), Less);
}

//入队列
void PriorityQueuePush(PQueue q, DataType data)
{
    assert(q);

    InsertHeap(&(q->_hp), data);
}

//出队列
void PriorityQueuePop(PQueue q)
{
    assert(q);
    DeleteHeap(&(q->_hp));
}

//查看队头元素
DataType PriorityQueueFront(PQueue q)
{
    assert(q);

    return HeapTop(&(q->_hp));

}

//查看队尾元素
DataType PriorityQueueBack(PQueue q)
{
    assert(q);

    if (!EmptyHeap(&(q->_hp)))
        return q->_hp.arr[q->_hp._size - 1];

    return 0;
}

//查看元素个数
int PriorityQueueSize(PQueue q)
{
    assert(q);

    return HeapSize(&(q->_hp));
}

//队列判空
int PriorityQueueEmpty(PQueue q)
{
    assert(q);

    return EmptyHeap(&(q->_hp));
}

//销毁队列
void PriorityQueueDestory(PQueue q)
{
    assert(q);

    DestoryHeap(&(q->_hp));
}

test.c

#include "PriorityQueue.h"




void Test2()
{
    PriorityQueue q;

    PriorityQueueInit(&q);
    PriorityQueuePush(&q, 53);
    PriorityQueuePush(&q, 17);
    PriorityQueuePush(&q, 78);
    PriorityQueuePush(&q, 9);
    PriorityQueuePush(&q, 45);
    PriorityQueuePush(&q, 65);
    PriorityQueuePush(&q, 87);
    PriorityQueuePush(&q, 23);
    PriorityQueuePush(&q, 31);
    printf("Front = %d Back = %d Size = %d\n", PriorityQueueFront(&q), PriorityQueueBack(&q), PriorityQueueSize(&q));
    PriorityQueuePop(&q);
    printf("Front = %d Back = %d Size = %d\n", PriorityQueueFront(&q), PriorityQueueBack(&q), PriorityQueueSize(&q));

    PriorityQueueDestory(&q);
}


int main()
{

    Test2();//测试优先级队列

}

堆排:

现在学过的的排序方法有:冒泡排序和选择排序,他们的时间复杂度都是O(n),都不是特别好,而堆排的时间复杂度是多少呢?堆排的具体代码如下:

//堆排
//升序--大堆
//降序--小堆
void AdjustHeap(int* arr, int size, int parent)
{
    int child = (parent << 1) + 1;
    assert(arr);

    while (child < size)
    {
        if (child + 1 < size && arr[child] > arr[child + 1])
            child += 1;

        if (arr[parent] > arr[child])
        {
            _Swap(arr + parent, arr + child);
            parent = child;
            child = (parent << 1) + 1;
        }

        else
            return;
    }
}
void HeapSort(int* arr, int size)
{
    int root = (size - 2) >> 1;
    int i = 0;
    int end = size - 1;

    assert(arr);

    //建堆
    for (i = root; i >= 0; i--)
        AdjustHeap(arr, size, i);

    //排序--将堆顶元素“删除”
    while (end)
    {
        _Swap(arr + 0, arr + end);
        AdjustHeap(arr, end, 0);

        end--;

    }
}

int main()
{

    int i = 0;
    int arr[] = { 8, 9, 2, 78, 54, 1, 0 };
    int size = sizeof(arr) / sizeof(arr[0]);

    HeapSort(arr, size);
    for (; i < size; i++)
        printf("%d ", arr[i]);

}

根据上面的代码,很容易求出其时间复杂度为:nlog2^n,比冒泡和选择排序都要好。

猜你喜欢

转载自blog.csdn.net/virgofarm/article/details/80312007