|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 pyzyd 于 2025-10-11 15:56 编辑
堆有最大堆和最小堆,
堆是完全二叉树,
要求:
1.每个父节点大于(或小于)等于其子节点,左右子节点没有大小要求
2.堆最多只能有一个单个的左子节点,不能有多个结点,不能是单个的右子节点
- 90
- / \
- 70 80
- / \ / \
- 60 20 75 50
- 这就是一个最大堆
- 错误示例
- 1
- / \
- 2 3
- / /
复制代码
堆的代码实现
- /*
- 堆是特殊的树,
- 堆是完全二叉树,
- 堆中每一个节点的值都大于或等于其左右孩子节点的值,称为大顶堆(最大堆);
- 堆中每一个节点的值都小于或等于其左右孩子节点的值,称为小顶堆(最小堆)。
- 堆可以用数组表示,数组中第i个元素,其左孩子为2i+1,右孩子为2i+2。
- */
- #include <cstring>
- #include <iomanip>
- #include <iostream>
- #include <string>
- #include <cmath>
- #define DEFAULT_CAPCITY 128
- typedef int DataType;
- typedef struct _Heap {
- DataType *data;
- int size;
- int capacity;
- } Heap;
- bool initHeap(Heap &heap, int *original, int size);
- bool insert(Heap &heap, DataType value);
- static void buildHeap(Heap &heap);
- static void adjustDown(Heap &heap, int index);
- static void adjustUp(Heap &heap, int index);
- int main() {
- Heap hp;
- int origVals[] = {1, 2, 3, 87, 93, 82, 92, 86, 95};
- if (!initHeap(hp, origVals, sizeof(origVals) / sizeof(origVals[0]))) {
- std::cerr << "init heap failed!" << std::endl;
- return -1;
- }
- if (typeid(1.0) == typeid(float)) {
- std::cout << "1.0 is float" << std::endl;
- } else {
- std::cout << "1.0 is double" << std::endl;
- }
- insert(hp, 100);
- return 0;
- }
- bool initHeap(Heap &heap, int *original, int size) {
- if (original == nullptr || size <= 0) {
- return false;
- }
- heap.capacity = DEFAULT_CAPCITY > size ? DEFAULT_CAPCITY : size;
- heap.data = new DataType[heap.capacity];
- if (!heap.data) {
- return false;
- }
- memcpy(heap.data, original, size * sizeof(int));
- heap.size = size;
- buildHeap(heap);
- return true;
- }
- bool insert(Heap &heap, DataType value) {
- if (heap.size == heap.capacity) {
- return false;
- }
- int index = heap.size++;
- heap.data[index] = value;
- adjustUp(heap, index);
- return true;
- }
- /*
- 从最后一个非叶子结点(父节点 size / 2 - 1
- 的位置)逐个往前调整所有父节点(直到根节点),
- 确保每一个父节点都是一个最大堆,最终整个堆就是一个最大堆。
- */
- static void buildHeap(Heap &heap) {
- int i;
- for (i = heap.size / 2 - 1; i >= 0; i--) {
- adjustDown(heap, i);
- }
- }
- /*
- 将当前节点和子节点调整成最大堆
- */
- static void adjustDown(Heap &heap, int index) {
- int cur = heap.data[index];
- int parent, child;
- for (parent = index; (parent * 2 + 1) < heap.size; parent = child) {
- child = parent * 2 + 1;
- // 比较左子节点和右子节点,取较大的那个
- if ((child + 1) < heap.size &&
- heap.data[child] < heap.data[child + 1]) {
- child++;
- }
- // 如果当前节点大于等于最大子节点,则不需要调整
- if (cur >= heap.data[child]) {
- break;
- } else {
- // 否则,将当前节点和最大子节点交换
- heap.data[parent] = heap.data[child];
- heap.data[child] = cur;
- }
- }
- }
- static void adjustUp(Heap &heap, int index) {
- if (index < 0 || index >= heap.size) {
- return;
- }
- while (index > 0) {
- int parent = (index - 1) / 2;
- if (heap.data[index] <= heap.data[parent]) {
- break;
- }
- // 交换当前节点与父节点
- int temp = heap.data[index];
- heap.data[index] = heap.data[parent];
- heap.data[parent] = temp;
- index = parent;
- }
- }
复制代码
|
|