#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