当前位置:   article > 正文

数据结构初阶 堆(一)

数据结构初阶 堆(一)

一. 堆的概念和性质

我们在上一篇博客介绍存储二叉树的两种方式

分别是顺序结构和链式结构

数据结构初阶 初识二叉树-CSDN博客

1. 堆的概念

这里注意!!! 这里说的堆和操作系统里面的堆没有半点关系!!!

如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

上面这个就是官方的解释了

但是要是我们用通俗的话来说

就是这样子的

大堆 就是所有的父节点都大于等于子节点的堆

小堆 就是所有的子节点都小于等于父节点的堆

如图

2. 堆的性质

  1. 堆总是一棵完全的二叉树

  2. 堆中某个节点的值总是不大于或者不小于其父节点的值

3. 小题目练练手

1.下列关键字序列为堆的是:()

A 100,60,70,50,32,65
B 60,70,65,50,32,100
C 65,100,70,32,50,60
D 70,65,100,32,50,60
E 32,50,100,70,65,60
F 50,100,70,65,60,32

我们首先来看A

很明显 满足大堆的定义

所以该题选A

我们再来看看B是不是错的

很明显是错的

所以更加确定了答案是A

二. 代码实现以及堆的部分接口函数

1. 结构体代码

结构体代码表示如下

  1. typedef int HPDateType;
  2. typedef struct Heap
  3. {
  4. HPDateType* a;
  5. int size;
  6. int capacity;
  7. }HP;

2. 初始化以及销毁

这两段代码很简单 这里就连起来写了

  1. void HeapInit(HP* php)
  2. {
  3. assert(php);
  4. php->a = (HPDateType*)malloc(sizeof(HPDateType) * 4);
  5. if (php->a == NULL)
  6. {
  7. perror("malloc fail");
  8. return;
  9. }
  10. php->size =0;
  11. php->capacity = 4;
  12. }
  13. void HeapDestroy(HP* php)
  14. {
  15. assert(php);
  16. free(php->a);
  17. php = NULL;
  18. php->size = 0;
  19. php->capacity = 0;
  20. }

两段代码表示如上

3. 增加数据 (大堆为例)

void HeapPush(HP* php, HPDateType x)

我们这里增加数据要先考虑一点

储存数据的空间够不够

如果不够的话我们就要扩容空间了

这一段代码已经讲过很多次了

我就不讲解了

判断代码如下

  1. assert(php);
  2. if (php->size == php->capacity)
  3. {
  4. HPDateType* tmp = (HPDateType*)realloc(php->a,sizeof(HPDateType) * php->capacity * 2);
  5. if (tmp == NULL)
  6. {
  7. perror("realloc fail");
  8. return;
  9. }
  10. php->a = tmp;
  11. php->capacity *= 2;
  12. }
  13. php->a[php->size] = x;
  14. php->size++;

 

当我们这里插入一个75的时候 这里明显是错误的啊 怎么办呢?

这个时候我们就需要将它跟它的父亲比较 是否大于它的父亲

如果不大于就填入

如果小于就交换它和它的父亲

知道孩子等于0为止

下面开始写代码

我们用一个函数来写 防止要复用

  1. void Swap(HPDateType* p1, HPDateType* p2)
  2. {
  3. HPDateType x = *p1;
  4. *p1 = *p2;
  5. *p2 = x;
  6. }
  7. //除child这个位置,前面数据构成堆
  8. //向上调整
  9. void AdJustUp(HPDateType* a, int child)
  10. {
  11. int parent = (child - 1) / 2;
  12. while (child > 0)
  13. {
  14. if (a[child] > a[parent])
  15. {
  16. Swap(&a[child], &a[parent]);
  17. child = parent;
  18. //更新父亲的位置
  19. parent = (child - 1) / 2;
  20. }
  21. else
  22. {
  23. break;
  24. }
  25. }
  26. }
  27. void HeapPush(HP* php, HPDateType x)
  28. {
  29. assert(php);
  30. if (php->size == php->capacity)
  31. {
  32. HPDateType* tmp = (HPDateType*)realloc(php->a,sizeof(HPDateType) * php->capacity * 2);
  33. if (tmp == NULL)
  34. {
  35. perror("realloc fail");
  36. return;
  37. }
  38. php->a = tmp;
  39. php->capacity *= 2;
  40. }
  41. php->a[php->size] = x;
  42. php->size++;
  43. AdJustUp(php->a, php->size - 1);
  44. }

整体代码表示如上

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/703424
推荐阅读
相关标签
  

闽ICP备14008679号