树的储存形势&代码实现(跑路人笔记2)

简介: 树的储存形势&代码实现(跑路人笔记)

main.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Heap.h"
//堆的测试
void HeapTest()
{
  Heap hp = {0};
  HeapCreat(&hp);
  HeapPush(&hp, 10);
  HeapPush(&hp, 18);
  HeapPush(&hp, 19);
  HeapPush(&hp, 25);
  HeapPush(&hp, 28);
  HeapPush(&hp, 43);
  HeapPush(&hp, 65);
  HeapPush(&hp, 49);
  HeapPush(&hp, 27);
  HeapPush(&hp, 37);
  HeapPop(&hp);
  HeapPrint(&hp);
  HeapDestory(&hp);
}
//堆排序
void HeapSort(int* a, int size)
{
  Heap hp;
  HeapCreat(&hp);
  for (int i = 0; i < size; ++i)
  {
    HeapPush(&hp, a[i]);
  }
  size_t j = 0;
  while (!HeapEmpty(&hp))
  {
    a[j] = HeapTop(&hp);
    j++;
    HeapPop(&hp);
  }
  HeapDestory(&hp);
}
int main()
{
  //TestHeap();
  int a[] = { 4, 2, 7, 8, 5, 1, 0, 6 };
  HeapSort(a, sizeof(a) / sizeof(int));
  for (int i = 0; i < sizeof(a) / sizeof(int); ++i)
  {
    printf("%d ", a[i]);
  }
  printf("\n");
  return 0;
}

咱主要讲Heap.c所需要讲解的部分

主要讲解部分

下方是结构题的内容

typedef struct Heap
{ 
  HPDataType* data;//用于储存数据
  size_t size; //大小
  size_t capacity;//容量
}Heap;

实话实说需要重点讲解的主要是两个函数.

其中

void AdJustUp(Heap* obj)
{
  size_t child = obj->size-1;
  size_t parent = (child - 1) / 2;
  while (child)
  {
    if (obj->data[parent] > obj -> data[child])
    {
      HPDataType tmp = obj->data[child];
      obj->data[child] = obj->data[parent];
      obj->data[parent] = tmp;
      child = parent;
      parent = (child - 1) / 2;
    }
    else
    {
      break;
    }
  }
}

这个函数是嵌套在HeapPush中的一个用于调整数据位置的函数,我们在HeapPush的时候是将数据直接放在我们顺序表的末尾处,然后通过AdJustUp函数对数据进行调整.将本来插入后可能不是堆情况调整成堆的格式.


我们通过图来了解这种情况: 比如我们的数值原来有着: 2 3 5 6 7 8


image.png


这时我们插入一个1来看看我们的AdJustUp函数是如何将顺序表的储存情况重新换成堆形势.


image.png


其实很简单我们通过while循环和if语句来判断末尾部的父亲是否大于我们要改变位置的节点如果大于就交换他们的位置如果小于就直接进行break语句跳出循环即可.


image.png


然后使我们的向下调整函数.

void AdJustDown(Heap* obj)
{
  size_t father = 0;
  size_t child = father*2+1;//得到的是左孩子
  while (child < obj->size)
  {
    //选出最小的孩子
    if (child+1<obj->size&&obj->data[child] > obj->data[child + 1])
    {
      child++;
    }
    if (obj->data[child] < obj->data[father])
    {
      HPDataType tmp = obj->data[child];
      obj->data[child] = obj->data[father];
      obj->data[father] = tmp;
      father = child;
      child = father * 2 + 1;
    }
    else
    {
      break;
    }
  }
}
void HeapPop(Heap* obj)
{
  assert(obj);
  assert(obj->size > 0);
  obj->data[0] = obj->data[obj->size - 1];
  obj->size--;
  AdJustDown(obj);
}


我们的向下调整函数也是在HeapPop函数内作为内嵌(至于为啥要把向下调整专门分装成一个函数,我个人认为是为了代码的整洁性吧).


HeapPop 的功能是删除顺序表的定元素也就是下标为0的元素,但是我们如果先将下标为0的元素换成我们在尾的元素然后进行对size进行--即可.


然后我们即可进行向下调整的操作.


老样子我们使用图文调整的形式给大家展示.


image.png


我们先比较左右还在的大小选一个最小的与父亲节点交换在只有一个孩子的情况至于左孩子比较即可👍.


结尾

这部分的代码实现其实也挺简单的,我们想用堆排序也只需要从得到头元素然后删头只要堆为空即可👍.


相关文章
|
自然语言处理 监控 数据挖掘
【Flink】Flink中的窗口分析
【4月更文挑战第19天】【Flink】Flink中的窗口分析
|
自然语言处理 PyTorch 算法框架/工具
安装ModelScope问题之官方指导的环境搭建会报错如何解决
本合集将提供ModelScope安装步骤、配置要求和环境准备,以便用户顺利启动ModelScope进行模型开发和测试。
393 0
|
9月前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
209 13
|
12月前
|
Java API Spring
在 Spring 配置文件中配置 Filter 的步骤
【10月更文挑战第21天】在 Spring 配置文件中配置 Filter 是实现请求过滤的重要手段。通过合理的配置,可以灵活地对请求进行处理,满足各种应用需求。还可以根据具体的项目要求和实际情况,进一步深入研究和优化 Filter 的配置,以提高应用的性能和安全性。
|
10月前
|
Java 编译器 UED
Arrays.asList() 数组转换成集合酿成的线上事故,差点要滚蛋了!
本文介绍了Java开发中使用`Arrays.asList()`方法将数组转换为集合时的一个常见陷阱。该方法返回的List是固定长度的,不支持添加或删除操作,直接使用可能导致线上故障。文章通过一次实际开发中的事故案例,分析了问题的原因,并提供了使用`java.util.ArrayList`进行封装的解决方案,以避免此类错误的发生。希望读者能从中吸取教训,提高代码的健壮性。
|
11月前
|
JavaScript 前端开发 API
探索组合式API的革新与优势
探索组合式API的革新与优势
152 1
|
11月前
|
监控 自动驾驶 机器人
5G技术在智能制造中的融合应用
5G技术在智能制造中的融合应用
276 0
|
机器学习/深度学习 自然语言处理 算法
【论文解读】文本分类上分利器:Bert微调trick大全
【论文解读】文本分类上分利器:Bert微调trick大全
1039 0
【论文解读】文本分类上分利器:Bert微调trick大全
HttpURLConnection中请求头中携带Token的使用方法
HttpURLConnection中请求头中携带Token的使用方法
698 2
|
前端开发 小程序 API
钉钉小程序的后端想要直接获取用户token,只能是前端通过dd.getAuthCode这种方式拿authCode吗?
钉钉小程序的后端想要直接获取用户token,只能是前端通过dd.getAuthCode这种方式拿authCode吗?
520 0