当前位置: 首页 > news >正文

二叉树的顺序存储

目录

顺序存储:

简介:

节点的位置关系:

优缺点:

优点:

缺点:

二叉树顺序存储的模拟实现:

向上调整算法:

向下调整算法:

二叉树的初始化:

直接初始化:

建堆初始化:

二叉树的头删:

二叉树的尾插:

二叉树的取顶端元素:

二叉树的判空:

二叉树的销毁:

完整代码:


顺序存储:

简介:

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,关于堆我们后面的章节会专门讲解。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。

节点的位置关系:

对于任意节点,设其在数组中的索引为 i(索引从0开始),则:

  • 父节点的索引为 (i-1)/2(向下取整)
  • 左子节点的索引为 2*i + 1
  • 右子节点的索引为 2*i + 2

优缺点:

优点

  • 访问任意节点的时间复杂度为O(1),因为可以直接通过索引访问。
  • 对于完全二叉树和满二叉树,空间利用率高。

缺点

  • 适用于完全二叉树或满二叉树,对于一般的二叉树,存在大量的空间浪费。
  • 插入和删除操作复杂,需要移动大量节点以保持树的顺序存储结构。

二叉树顺序存储的模拟实现:

向上调整算法:

void AdjustUp(HeapDataType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

向下调整算法:

void Adjustdown(HeapDataType* a, int n, int parent)
{size_t child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child + 1] < a[child]){child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

二叉树的初始化:

直接初始化:

void HeapInit(HP* php)
{php->a = NULL;php->capacity = 0;php->size = 0;
}

建堆初始化:

void HeapInitArrey(HP* php, HeapDataType* a, int n)
{assert(php);php->a = (HeapDataType*)malloc(sizeof(HeapDataType) * n);if (php->a == NULL){perror("malloc fail:");return;}memcpy(php->a, a, sizeof(HeapDataType) * n);
}

二叉树的头删:

void HeapPop(HP* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;Adjustdown(php->a, php->size, 0);
}

二叉树的尾插:

void HeapPush(HP* php, HeapDataType x)
{if (php->size == php->capacity){size_t newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;HeapDataType* tmp = realloc(php->a, sizeof(HeapDataType) * newcapacity);php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}

二叉树的取顶端元素:

HeapDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}

二叉树的判空:
 

bool Empty(HP* php)
{assert(php);return php->size == 0;
}

二叉树的销毁:

void HeapDestory(HP* php)
{free(php);php->a = NULL;php->capacity = 0; php->size = 0;
}

完整代码:

#include "heap.h"
void HeapInit(HP* php)
{php->a = NULL;php->capacity = 0;php->size = 0;
}void HeapInitArrey(HP* php, HeapDataType* a, int n)
{assert(php);php->a = (HeapDataType*)malloc(sizeof(HeapDataType) * n);if (php->a == NULL){perror("malloc fail:");return;}memcpy(php->a, a, sizeof(HeapDataType) * n);
}void HeapPush(HP* php, HeapDataType x)
{if (php->size == php->capacity){size_t newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;HeapDataType* tmp = realloc(php->a,sizeof(HeapDataType) * newcapacity);php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);
}void HeapPop(HP* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;Adjustdown(php->a, php->size, 0);
}void Swap(HeapDataType* x, HeapDataType* y)
{HeapDataType* tmp = *x;*x = *y;*y = tmp;
}void AdjustUp(HeapDataType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}void Adjustdown(HeapDataType* a, int n, int parent)
{size_t child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child + 1] < a[child]){child++;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}HeapDataType HeapTop(HP* php)
{assert(php);return php->a[0];
}bool Empty(HP* php)
{assert(php);return php->size == 0;
}void HeapDestory(HP* php)
{free(php);php->a = NULL;php->capacity = 0; php->size = 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • linux 进程堆栈分析
  • 精通C#编程需要学习哪些常用框架?
  • [安洵杯 2019]easy_serialize_php
  • 小型简易GIT服务器搭建和使用
  • 基于Memcached实现对象缓存:存储对象数据,如购物车内容,用户配置
  • 深入理解Spring Boot中的数据库优化
  • 音视频封装demo:将h264数据和aac数据封装(mux)成TS文件(纯手工,不依赖第三方开源库)
  • DDD架构
  • 快速将一个网址打包成一个exe可执行文件
  • 大数据基础:Hadoop之HDFS重点架构原理
  • CentOS 8升级gcc版本
  • redis的Bitmap 、HyperLogLog、Geo相关命令和相关场景
  • AtCoder Beginner Contest 361
  • SQL 字段类型-上
  • 旗晟机器人AI智能算法有哪些?
  • 3.7、@ResponseBody 和 @RestController
  • Android组件 - 收藏集 - 掘金
  • ECMAScript入门(七)--Module语法
  • ES6 学习笔记(一)let,const和解构赋值
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • HTML-表单
  • iOS小技巧之UIImagePickerController实现头像选择
  • javascript 总结(常用工具类的封装)
  • Rancher如何对接Ceph-RBD块存储
  • REST架构的思考
  • Selenium实战教程系列(二)---元素定位
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 码农张的Bug人生 - 见面之礼
  • 前端设计模式
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 浅谈web中前端模板引擎的使用
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 怎么将电脑中的声音录制成WAV格式
  • k8s使用glusterfs实现动态持久化存储
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • ​字​节​一​面​
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • # Spring Cloud Alibaba Nacos_配置中心与服务发现(四)
  • #define
  • (+4)2.2UML建模图
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (3)STL算法之搜索
  • (4)(4.6) Triducer
  • (C语言)字符分类函数
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (web自动化测试+python)1
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .NET DevOps 接入指南 | 1. GitLab 安装
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net的socket示例