数据结构 | 最大堆、最小堆、优先队列

01 二叉堆 | 二叉堆本质上是一种完全二叉树

  • 二叉堆的根结点叫做堆顶
1. 最大堆
  • 最大堆任何一个父结点的值,都大于等于它左右孩子结点的值。
  • 最大堆的堆顶是整个堆中的最大元素
2. 最小堆
  • 最小堆任何一个父结点的值,都小于等于它左右孩子结点的值。
  • 最小堆的堆顶是整个堆中的最小元素。
如何构建一个堆呢?
  • 这就需要依靠二叉堆的自我调整。
堆的自我调整

对于二叉树,如下有几种操作:

  • 插入结点
  • 删除结点
  • 构建二叉堆

02 举例:最小堆的自我调整

初始堆

插入数值举例

  • 向初始堆中插入数值3时,首先在堆的末尾插入该数值,然后不断向上提升直到没有大小颠倒为止。
  • 上浮

取出最小值举例

  • 从堆中删除最小值时,首先把堆的最后一个节点的数值复制到根节点上,并且删除最后一个节点。然后不断向下交换直到没有大小颠倒为止。
  • 下沉:在向下交换的过程中,如果有2个儿子,选择数值较小的儿子进行交换。

构建二叉树

  • 构建二叉树,也就是把一个无序的完全二叉树调整为二叉堆,本质上就是让所有非叶子结点依次下沉。

堆的实现

  • 二叉堆虽然是一棵完全二叉树,但它的存储方式并不是链式存储,而是顺序存储 换句话说,二叉堆的所有结点都存储在数组当中。
堆操作的时间复杂度
  • 堆的两种操作(插入、删除)所花的时间都和树的深度成正比。
  • 如果一共有n个元素,那么每个操作可以在O(logn)的时间内完成。

03 堆的应用场景

  • 堆排序
  • 优先级队列

04 优先队列

满足操作:

  • 插入一个数值
  • 取出最小的数值(获得数值,并且删除)

实现:堆

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最小堆是一种常用的数据结构,可以用来实现优先队列。下面是一个使用C语言实现最小堆优先队列的代码示例: ```c #include <stdio.h> #define MAX_SIZE 100 // 最小堆结构 typedef struct { int heap[MAX_SIZE]; // 存储元素的数组 int size; // 当前中元素的个数 } MinHeap; // 初始化最小堆 void initMinHeap(MinHeap* minHeap) { minHeap->size = 0; } // 向最小堆中插入元素 void insert(MinHeap* minHeap, int value) { if (minHeap->size == MAX_SIZE) { printf("最小堆已满,无法插入新元素!\n"); return; } int i = ++(minHeap->size); // 元素个数加一,i指向新插入的元素位置 while (i > 1 && value < minHeap->heap[i / 2]) { minHeap->heap[i] = minHeap->heap[i / 2]; // 将父节点下移 i /= 2; } minHeap->heap[i] = value; // 插入新元素 } // 删除最小堆中的最小元素并返回该元素值 int deleteMin(MinHeap* minHeap) { if (minHeap->size == 0) { printf("最小堆为空,无法删除最小元素!\n"); return -1; } int min = minHeap->heap[1]; // 最小元素即为顶元素 int lastValue = minHeap->heap[(minHeap->size)--]; // 取出最后一个元素,size减一 int parent = 1, child = 2; // parent表示当前节点的父节点,child表示当前节点的左子节点 while (child <= minHeap->size) { // 若右子节点存在且比左子节点小,则用右子节点来比较 if (child < minHeap->size && minHeap->heap[child] > minHeap->heap[child + 1]) { child++; } // 若最后一个元素小于等于当前子节点值,则找到了插入位置,退出循环 if (lastValue <= minHeap->heap[child]) { break; } minHeap->heap[parent] = minHeap->heap[child]; // 将子节点上移 parent = child; child *= 2; } minHeap->heap[parent] = lastValue; // 插入最后一个元素 return min; } int main() { MinHeap minHeap; initMinHeap(&minHeap); insert(&minHeap, 5); insert(&minHeap, 3); insert(&minHeap, 7); insert(&minHeap, 1); printf("删除的最小元素为:%d\n", deleteMin(&minHeap)); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值