数据结构之堆

简介: 数据结构之堆

在前面的学习中,我们已经学习了数据结构中的顺序表,链表,栈,队列。这些数据结构都是线性数据结构,从这篇文章开始,我们将要研究这种非线性数据结构。

堆的介绍

首先介绍一下什么是树

树是有限个节点构成的具有层次关系的集合。因为这种关系的逻辑图看起来像一颗倒挂的树,故叫做树。

其次介绍一下树的种类

树又分为二叉树非二叉树,二叉树又分为完全二叉树满二叉树。这篇文章主要详细介绍,堆是一种完全二叉树

其次介绍一下堆的种类

堆又分为大堆,小堆。大堆:父节点大于等于子节点  小堆:父节点小于等于子节点

堆的实现

堆的实现:堆的逻辑结构是完全二叉树,存储结构是顺序结构。下面以小堆的实现为例。

要实现堆,首先明白堆的逻辑结构完全二叉树存储结构顺序表

在完全二叉树中,有如下结论

父节点找左孩子:parent*2+1

父节点找右孩子:parent*2+2

孩子找父节点:(child-1)/2

heap.h

 

heap.c

堆的初始化

1. void IntiHeap(Hp* heap)
2. {
3.  assert(heap);
4. //malloc一块空间,用来初始化顺序表
5.  DateType* tmp = (DateType*)malloc(4 * sizeof(DateType));
6.  assert(tmp);//保证malloc成功
7.  heap->arr = tmp;//初始化顺序表
8.  heap->size = 0;//有效数据个数0
9.  heap->capcity = 4;//初始容量4
10. }

堆的销毁

1. void DestoryHeap(Hp* heap)
2. {
3.  assert(heap);
4.  free(heap->arr);//释放顺序表空间
5.  heap->arr = NULL;//将指针置空,避免成为野指针
6.  heap->size = 0;//有效数据置0
7.  heap->capcity = 0;//容量置0
8. }

堆的插入

堆的插入是这里的关键,这里以小堆为例,欲在小堆里插入一个元素,这里的步骤为:

step1.直接插入到堆尾        step2.向上调整。

1. void HeapPush(Hp* heap, DateType n)
2. {
3.  assert(heap);
4.  if (heap->size == heap->capcity)//检查容量
5.  {
6.    //扩容
7.    DateType* tmp = realloc(heap->arr, 2 * heap->capcity * sizeof(DateType));
8.    assert(tmp);
9.    heap->arr = tmp;
10.     heap->capcity *= 2;
11.   }
12.   //直接插入,未做调整step1
13.   heap->arr[heap->size] = n;
14.   heap->size++;
15.   //向上调整step2
16.   UpAdjust(heap->arr, heap->size - 1);//参数为堆的存储顺序表和堆尾节点下标(孩子)
17. }

向上调整算法

1. void UpAdjust(DateType* arr, int child)//向上调整算法
2. {
3.  int parent = (child - 1) / 2;//找到父亲节点
4.  while (child != 0)//直到child成为0,不需要向上调整
5.  {
6.    if (arr[child] < arr[parent])//如果不满足小堆定义
7.    {
8.      //交换
9.      swap(&arr[child],&arr[parent]);
10.     }
11.     else//满足就不需要向上调整了
12.     {
13.       break;
14.     }
15. //向上迭代child,parent
16.     child = parent;
17.     parent = (child - 1) / 2;
18.   }
19. }

堆顶元素删除

堆顶元素删除的步骤为:

step1.交换堆顶元素和堆尾元素,直接删除堆尾元素    step2.向下调整堆。

1. void HeapPop(Hp* heap)
2. {
3.  assert(heap);
4.  assert(!HeapEmpty(heap));//保证堆不为空
5.  //step1:先交换,再size--,再调整堆
6.  swap(&heap->arr[0], &heap->arr[heap->size - 1]);
7.  heap->size--;
8.  //step2:调堆,向下调整算法
9.  DownAdjust(heap->arr, heap->size, 0);
10. }

向下调整算法:

step2

1. //堆的存储结构 堆的有效数据个数 向下调整起始父节点
2. void DownAdjust(DateType* arr, int size, int parent)
3. {
4.  int child = parent * 2 + 1;//找到左孩子
5.  while (child<size)
6.  {
7. //防止没有右孩子,越界
8.    if (child+1<size&&arr[child] > arr[child + 1])//调整并找到数据较小的child
9.    {
10.       child++;//由左孩子变为右孩子
11.     }
12. 
13.     if (arr[child] < arr[parent])//如果不满足小堆定义
14.     {
15.       swap(&arr[child], &arr[parent]);//交换
16. //迭代
17.       parent = child;
18.       child = parent * 2 + 1;
19.     }
20.     else
21.     {
22.       break;
23.     }
24.   }
25. }

判断堆是否为空

1. bool HeapEmpty(Hp* heap)
2. {
3.  assert(heap);
4.  return heap->size == 0;
5. }

获取堆顶元素

1. DateType TopHeap(Hp* heap)
2. {
3.  assert(heap);
4.  return heap->arr[0];
5. }

获取堆有效数据

1. int HeapSize(Hp* heap)
2. {
3.  return heap->size;
4. }


相关文章
|
15小时前
|
存储 JavaScript 前端开发
什么是堆?什么是栈?他们之间从区别和联系
什么是堆?什么是栈?他们之间从区别和联系
33 0
|
15小时前
|
存储 缓存 算法
堆和栈的概念和区别
堆和栈的概念和区别
19 1
|
15小时前
|
存储 算法
【数据结构入门指南】二叉树顺序结构: 堆及实现(全程配图,非常经典)
【数据结构入门指南】二叉树顺序结构: 堆及实现(全程配图,非常经典)
32 0
|
15小时前
|
算法
数据结构之堆的结构与实现
数据结构之堆的结构与实现
|
15小时前
|
存储 算法
【堆】数据结构堆的实现(万字详解)
【堆】数据结构堆的实现(万字详解)
|
15小时前
|
存储 机器学习/深度学习 大数据
数据结构——堆
数据结构——堆
30 0
|
15小时前
|
存储 机器学习/深度学习
数据结构--二叉树-堆(1)
数据结构--二叉树-堆(1)
数据结构--二叉树-堆(1)
|
15小时前
|
存储 机器学习/深度学习 算法
数据结构与算法:堆
朋友们大家好啊,本篇文章来到堆的内容,堆是一种完全二叉树,再介绍堆之前,我们首先对树进行讲解
数据结构与算法:堆
|
15小时前
|
存储 程序员
什么是堆,什么是栈
什么是堆,什么是栈
7 0
|
15小时前
【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)
【数据结构】二叉树-堆(top-k问题,堆排序,时间复杂度)
17 4

热门文章

最新文章