#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