【数据结构】之用堆实现优先队列

#include <stdio.h>
#include <malloc.h>

/**
 * 使用堆来实现优先队列
 * 堆的最重要性质就是子节点的值>=父节点的值,
 * 而且树的节点是从上到下、从左到右的顺序紧凑排列的
 */

//这里我封装了一个二叉树
typedef struct BinaryTree{
    int *note;
    int size;
    void (*push)(struct BinaryTree* , int);
    int (*pop)(struct BinaryTree* );
} BinaryTree;

/**
 * 插入数值
 * 大致思路:首先在二叉树末尾添加此数值,然后如果它比父节点小就向上提升,
 * 直到不小于父节点或者已经移到根节点为止
 */
void tree_push(BinaryTree *this, int num){
    int parent = (this->size-1) / 2;
    int curIndex = this->size++;
    while (num < this->note[parent] && curIndex > 0){
        this->note[curIndex] = this->note[parent];
        curIndex = parent;
        parent = (parent-1) / 2;
    }
    this->note[curIndex] = num;
}

/**
 * 删除最小值
 * 大致思路:根节点就是最小值,把末尾的值赋在根节点上,然后删除末尾节点,
 * 然后不断向下交换直到没有大小颠倒为止,向下交换中,如果有两个子节点,
 * 则选择数值较小的子节点与其进行交换
 */
int tree_pop(BinaryTree *this){
    //最小值
    int ret = this->note[0];
    //末尾的元素
    int x = this->note[--this->size];
    int curIndex = 0;
    int a = curIndex * 2 + 1, b = curIndex * 2 + 2;
    while (x > this->note[a] && a < this->size){
        if (this->note[a] > this->note[b] && b < this->size)
            a = b;
        this->note[curIndex] = this->note[a];
        curIndex = a;
        a = curIndex * 2 + 1, b = curIndex * 2 + 2;
    }
    this->note[curIndex] = x;
    return ret;
}

//初始化
BinaryTree * new_BinaryTree(int max_size){
    BinaryTree *tree = malloc(sizeof(BinaryTree));
    tree->note = malloc(sizeof(int) * max_size);
    tree->size = 0;
    tree->pop = tree_pop;
    tree->push = tree_push;
    return tree;
}

//测试代码
int main() {
    BinaryTree *tree = new_BinaryTree(1000);
    tree->push(tree, 3);
    tree->push(tree, 1);
    tree->push(tree, 0);
    tree->push(tree, 2);
    tree->push(tree, 2);
    tree->push(tree, 1);
    tree->push(tree, 0);
    tree->push(tree, -1);
    for (int i = 0; i < tree->size; ++i) {
        printf("%d ",tree->note[i]);
    }
    printf("\n");
    tree->pop(tree);
    for (int i = 0; i < tree->size; ++i) {
        printf("%d ",tree->note[i]);
    }

    return 0;
}

运行结果:

-1 0 0 2 2 1 1 3
0 2 0 3 2 1 1





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值