当前位置:   article > 正文

【数据结构】堆的实现_堆的实现方法

堆的实现方法

目录

一、堆的概念

1.概念:

2.性质

二.堆的实现

1.用数组定义堆结构struct Heap

2.交换两个数swap函数

3.向下调整算法AdjustDown函数

4.向上调整算法AdjustUp函数

5.初始化堆HeapInit函数

6.销毁堆HeapDestory函数

7.堆的插入HeapPush函数

8.堆的删除HeapPop函数

9.取堆顶数据 HeapTop函数

10.取堆数据个数 HeapSize函数

11.堆判空 HeapEmpty函数


一、堆的概念

1.概念:

堆是将一个完全二叉树以顺序存储方式存储在数组中的一个数据结构,这颗完全二叉树需满足父节点的值大于等于(小于等于)孩子节点的值。
将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆的逻辑结构为完全二叉树,物理结构为一维数组

2.性质

(1)堆中某个节点的值总是不大于或不小于其父节点的值;(整个树所有结点需保持同一个规律,。要大于等于,都大于等于。反之同理)

(2)堆逻辑总是一棵完全二叉树

注:

一个升序(降序)的数组一定是堆

但堆的数组不一定就是升序(降序)

二.堆的实现

1.用数组定义堆结构struct Heap
  1. typedef struct Heap
  2. {
  3. HPDataType* _a;
  4. int _size;
  5. int _capacity;
  6. }Heap;
2.交换两个数swap函数
  1. void swap(HPDataType* p1, HPDataType* p2)
  2. {
  3. HPDataType tmp = *p1;
  4. *p1 = *p2;
  5. *p2 = tmp;
  6. }
3.向下调整算法AdjustDown函数

现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整 成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。   

int array[] = {27,15,19,18,28,34,65,49,25,37};

向下调整过程如图:

  1. //小堆
  2. void AdjustDown(Heap* hp, int parent)
  3. {
  4. int child = parent * 2 + 1;
  5. while (child<hp->_size)
  6. {
  7. //判断是否存在右孩子,且值小于左孩子
  8. if (child + 1 < hp->_size && hp->_a[child + 1] < hp->_a[child])
  9. {
  10. child++;
  11. }
  12. //判断parent节点和child节点的大小
  13. if (hp->_a[child] < hp->_a[parent])
  14. {
  15. swap(&(hp->_a[child]), &(hp->_a[parent]));
  16. parent = child;
  17. child = parent * 2 + 1;
  18. }
  19. else
  20. {
  21. break;
  22. }
  23. }
  24. }
4.向上调整算法AdjustUp函数

前提:插入前逻辑上为堆(大堆or小堆)

  1. //按小堆检查
  2. void AdjustUp(Heap* hp, int child)
  3. {
  4. int parent = (child - 1) / 2;
  5. while (child > 0)
  6. {
  7. if (hp->_a[parent] > hp->_a[child])
  8. {
  9. int tmp = hp->_a[child];
  10. hp->_a[child] = hp->_a[parent];
  11. hp->_a[parent] = tmp;
  12. }
  13. else
  14. {
  15. break;
  16. }
  17. child = parent;
  18. parent = (child - 1) / 2;
  19. }
  20. }
5.初始化堆HeapInit函数
  1. //初始化堆
  2. void HeapInit(Heap* hp)
  3. {
  4. assert(hp);
  5. hp->_a = NULL;
  6. hp->_capacity = hp->_size = 0;
  7. }
6.销毁堆HeapDestory函数
  1. // 堆的销毁
  2. void HeapDestory(Heap* hp)
  3. {
  4. free(hp->_a);
  5. free(hp);
  6. hp = NULL;
  7. }
7.堆的插入HeapPush函数
  1. // 堆的插入
  2. void HeapPush(Heap* hp, HPDataType x)
  3. {
  4. assert(hp);
  5. //判断堆是否已经满
  6. if (hp->_size == hp->_capacity)
  7. {
  8. int newcapacity = hp->_capacity == 0 ? 4 : 2 * hp->_capacity;
  9. int* tmp = (int*)realloc(hp->_a,sizeof(HPDataType) * newcapacity);
  10. if (tmp == NULL)
  11. {
  12. perror("realloc fail");
  13. return;
  14. }
  15. hp->_a = tmp;
  16. hp->_capacity = newcapacity;
  17. }
  18. hp->_a[hp->_size] = x;
  19. AdjustUp(hp, hp->_size);
  20. hp->_size++;
  21. }
8.堆的删除HeapPop函数
  1. //默认为删除堆顶
  2. //为了不影响整体结构,将堆顶元素与堆尾交换后,删除。之后需向下调整堆,维持堆的性质
  3. void HeapPop(Heap* hp)
  4. {
  5. assert(hp);
  6. assert(!HeapEmpty(hp));
  7. //交换
  8. swap(&(hp->_a[0]), &(hp->_a[hp->_size - 1]));
  9. //删除
  10. hp->_size--;
  11. //向下调整
  12. AdjustDown(hp, 0);
  13. }
9.取堆顶数据 HeapTop函数

因为物理结构是一个数组,所以取下标为0的数就是堆顶数据。

  1. // 取堆顶的数据
  2. HPDataType HeapTop(Heap* hp)
  3. {
  4. return hp->_a[0];
  5. }

10.取堆数据个数 HeapSize函数

直接输出size的大小。

  1. // 堆的数据个数
  2. int HeapSize(Heap* hp)
  3. {
  4. return hp->_size;
  5. }
11.堆判空 HeapEmpty函数

直接判断堆数据size的大小是否为0。

  1. // 堆的判空
  2. int HeapEmpty(Heap* hp)
  3. {
  4. return hp->_size == 0;
  5. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/944445
推荐阅读
相关标签
  

闽ICP备14008679号