美文网首页
大顶堆的实现.md

大顶堆的实现.md

作者: 突击手平头哥 | 来源:发表于2020-01-18 20:28 被阅读0次

大顶堆的实现.md

大顶堆介绍

  大顶堆的基础结构就是完全二叉树, 是一种基础的数据结构, 其特点是根节点是最大值(或最小值); 可以用于实现优先级队列或者堆排序

数组实现的大顶堆

  • 根节点处于index为0的位置, 节点的排布方式是广度优先: 第一层index=0, 第二层index = 1, 2...

  • 设二叉树节点的下标是n, 那么左孩子的下标是2n+1, 右孩子的下标是2n+2

  • 设二叉树节点的下标是n, 那么其父节点的下标是(n-1)/2

基本设计思想

push

  • 在数组的末尾插入, 然后与其父节点继续比较, 如果大于其父节点则进行交换, 循环往上直到根节点

  • 这样可以保证是一颗完全二叉树

pop操作

  • 使用最后一个节点的值替换index=0的位置

  • 然后与左右孩子比较, 如果小于其中任意一个与左右孩子中较大的一个进行替换操作

C语言实现

#include <string.h>

typedef struct heap_s heap_t;
int heap_valid = 0;

struct heap_s
{
    int size;
    int capacity;
    int data[0];
};  


heap_t* hp_alloc()
{
    heap_t* hp = (heap_t*)calloc(sizeof(heap_t) + sizeof(int)*8, 1);
    hp->size = 0;
    hp->capacity = 8;
    return hp;
}

int& hp_top(heap_t *hp)
{
    return hp->data[0]; 
}

int hp_pop(heap_t *hp)
{
    if(!hp || hp->size == 0)
    {
        heap_valid = 1;
        return 0;
    }

    int ret = hp->data[0];

    int len = --hp->size;
    hp->data[0] = hp->data[len];
    int *data = hp->data;

    int idx = 0;
    while(1)
    {
        int ls = 2*idx + 1;
        int rs = 2*idx + 2;
        int nt = -1;
        if((ls < len && data[idx] < data[ls]) && (rs < len && data[idx] < data[rs]))
        {
            nt = (data[ls] > data[rs]) ? ls : rs;
        }
        else if(ls < len && data[idx] < data[ls])
        {
            nt = ls; 
        }
        else if(rs < len && data[idx] < data[rs])
        {
            nt = rs;
        }

        if(nt >= 0)
        {
            int tmp = data[idx];
            data[idx] = data[nt]; 
            data[nt] = tmp;
            idx = nt;
        }
        else
            break;  
    }
    return ret;
} 

void hp_push(heap_t **rhp, int t)
{
    if(!rhp || !*rhp)   return;

    heap_t *hp = *rhp;

    if(hp->capacity == hp->size)
    {
        heap_t *nhp = (heap_t*)malloc(sizeof(heap_t) + sizeof(int)*(hp->capacity*2));
        memcpy(nhp, hp, sizeof(hp) + sizeof(int) * hp->capacity);           //?
        nhp->capacity = 2*hp->capacity;
        free(hp);
        hp = nhp;
        *rhp = hp;
    }
    hp->data[hp->size] = t;

    int idx = hp->size++;
    int par = (idx-1)/2;;
    while(idx > 0 && par >= 0 && (hp->data[par] < hp->data[idx]))
    {
        int tmp = hp->data[idx];
        hp->data[idx] = hp->data[par];
        hp->data[par] = tmp;
        idx = par;
        par = (idx-1)/2;
    }
}

相关文章

  • 大顶堆的实现.md

    大顶堆的实现.md 大顶堆介绍   大顶堆的基础结构就是完全二叉树, 是一种基础的数据结构, 其特点是根节点是最大...

  • 堆排序的实现

    用大顶堆实现堆排序

  • 大顶堆生成、新增、删除、排序javascript实现

    大顶堆小顶堆的概念和使用本文不赘述,使用js实现一个大顶堆的创建,新增,删除以及利用大顶堆排序

  • 堆排序的实现

    使用大顶锥实现升序排序,二叉堆的详细操作见以前的文章 步骤如下: 先构建大顶堆 然后循环删除堆顶元素(交互首尾元素...

  • 堆在java中的应用--PriorityQueue

    堆的特点 堆是一种完全二叉树的模拟,堆一般是基于数组的实现,堆分大顶堆和小顶堆,大顶堆就是堆顶是最大的数据,然后子...

  • 手把手教你写个大顶堆

    今天我们来实现一个大顶堆,所谓大顶堆,即根节点的值大于等于其孩子节点的值。废话少絮,直接开始。 堆是一个完全二叉树...

  • 算法:手动实现大顶堆、小顶堆

    在刷LeetCode时,经常看到Java系统函数PriorityQueue。swift中没有,只能手动构造一个了。...

  • 剑指offer 数据流中的中位数

    建立大顶堆和小顶堆

  • 堆-Heap

    堆-Heap 堆的基本接口设计 二叉堆(最大堆) 大顶堆-添加 大顶堆-删除 删除堆顶元素的同时插入一个新元素 大...

  • PriorityQueue 使用方法

    求最大k个元素的问题:使用小顶堆 求最小k个元素的问题:使用大顶堆 参考:1 采用PriorityQueue实现大...

网友评论

      本文标题:大顶堆的实现.md

      本文链接:https://www.haomeiwen.com/subject/zwhlzctx.html