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

二叉树的顺序存储

二叉树是一种非常重要的数据结构,不管是我们在考研中开始实际工作中,都不可避免使用二叉树,下面我用代码来给大家介绍一下如果用二叉树的顺序存储结构实现相关的操作

由于顺序存储结构的局限性,一般只适合存储完全二叉树

完全二叉树的顺序存储
#include<stdio.h>
#include<stdbool.h>
#include<math.h>
#define MaxSize 13//假设存储从1到12的完全二叉树
typedef struct TreeNode
{
int data;//数据域
bool isEmpty;//判断结点是否为空
int Length;//树的长度
}TreeNode;
void InitTree(TreeNode t[])
{
int i = 0;
for (i; i < MaxSize; i++)
{
t[i].isEmpty = true;//都赋值为空
}
t->Length = 0;
return;
}
bool InsertTree(TreeNode t[])//插入数据
{
if (t[MaxSize - 1].isEmpty == false)//数组已满
return false;
int i = 1;//从下标1开始,与树的根结点的数据域一一对应
for (i; i < MaxSize; i++)
{
t[i].data = i;
t[i].isEmpty = false;
t->Length++;
}
return true;
}
bool FindLeftSon(TreeNode t[], int i)//查找结点i的左孩子
{
if (2 * i >= MaxSize)//查找数大于数组长度
{
printf("无左孩子\n");
return false;
}
if (t[2 * i].isEmpty == true)
{
printf("左孩子为空\n");
return false;
}
int left = 2 * i;
printf("%d的左孩子为%d \n",i,left);
return true;
}
bool FindRightSon(TreeNode t[], int i)//查找结点i的右孩子
{
if (2 * i + 1 >= MaxSize)
{
printf("无右孩子\n");
return false;
}
if (t[2 * i + 1].isEmpty == true)
{
printf("右孩子为空\n");
return false;
}
int right = t[2 * i + 1].data;
printf("%d的右孩子为%d\n", i, right);
return true;
}
bool FindFatherNode(TreeNode t[], int i)//查找父结点
{
if (i == 1)
{
printf("根节点没有父节点\n");
return false;
}
int FatherNode = i / 2;//父节点的逻辑位置
if (FatherNode >= MaxSize || t[FatherNode].isEmpty == true)
{
printf("父节点不存在\n");
return false;
}
printf("%d的父节点为%d\n", i, FatherNode);
return true;
}

bool FindFloorNode(TreeNode t[], int i)//查找结点所在的层次
{
if (t[i].data >= MaxSize)
{
printf("树中无此树\n");
return false;
}
int Floor = ceil(log2(i + 1));//ceil()函数,把所得的小数向上取整,调用<math.h>库
printf("%d所在的层数是%d", i, Floor);
return true;
}
bool PrintTree(TreeNode t[])//打印测试树
{
int i = 1;
for (i; i < MaxSize; i++)
{
printf("%d ", t[i].data);
}
printf("\n");
return true;
}
int main()
{
TreeNode t[MaxSize];//存储树的数组
InitTree(t);//初始化树
InsertTree(t);//插入树的数据
FindLeftSon(t, 2);//查找左孩子
FindRightSon(t, 2);//查找右孩子
FindFatherNode(t, 2);//查找父结点
FindFloorNode(t, 2);//所在的层次
/*PrintTree(t);*/
return 0;
}

一般树的顺序结构实现

#include<stdio.h>
#include<stdbool.h>
#include<math.h>
#define Max 13
typedef struct TreeNode
{
int data;
bool isEmpty;
}TreeNode;
void InitTree(TreeNode t[])//初始化树
{
int i = 0;
for (i; i < Max; i++)
{
t[i].isEmpty = true;//都初始化为空
}
return;
}
bool InsertTree(TreeNode t[], int arr[],int * length)//插入数据
{
if (*length >= Max)
{
printf("无法插入\n");
return false;
}
int i = 1;
for (i; i < Max; i++)
{
if (arr[i] != 0)
{
t[i].data = i;
t[i].isEmpty = false;
*length++;
}
}
return true;
}
bool FindLeftSon(TreeNode t[], int i)//查找左孩子
{
if (i >= Max || t[i].isEmpty == true)
{
printf("该结点没有左孩子\n");
return false;
}
if (2 * i >= Max)
{
printf("结点超范围\n");
return false;
}
if (t[2 * i].isEmpty == true)
{
printf("左孩子为空\n");
return false;
}
int left = 2 * i;
printf("%d左孩子为%d\n", i,left);
return true;
}
bool FindRightSon(TreeNode t[], int i)//查找右孩子
{
//i结点是否合法
if (i >= Max || i <= 0)
{
printf("i超出范围\n");
return false;
}
if (t[i].isEmpty == true)
{
printf("结点不存在\n");
return false;
}
int right = 2 * i + 1;
//右孩子结点是否合法
if (right >= Max)
{
printf("右孩子超范围\n");
return false;
}
if (t[right].isEmpty == true)
{
printf("右孩子无结点\n");
return false;
}
printf("右孩子结点为%d\n", right);
return true;
}
bool FindFatherNode(TreeNode t[], int i)//查找i结点的父结点
{
if (i == 1)
{
printf("根结点无父结点");
return false;
}
int FatherNode = i / 2;
printf("%d的父结点为%d\n", i, FatherNode);
return true;
}
bool FindFloor(TreeNode t[], int i)//返回所在层数
{
if (i <= 0 || i >= Max)
{
printf("不在其范围\n");
return false;
}
int Floor = (int)ceil(log2(i + 1));//向上取整
printf("%d在第%d层\n", i, Floor);
return true;
}
bool PrintTreeNode(TreeNode t[])//打印测试
{
int i = 1;
for (i; i < Max; i++)
{
if (t[i].isEmpty == false)
{
printf("%d ", t[i].data);
}
}
printf("\n");

    return true;
}
int main()
{
int arr[Max] = { 1,2,3,5,6,7,11,12 };//假设二叉树的元素
int arr1[Max] = { 0 };
int i = 0;
int j = 0;
while (j < Max)
{
if (j == arr[i] && i < Max)
{
arr1[j] = arr[i];
i++;
}
j++;
}
TreeNode t[Max];
int length = 0;//树的长度
InitTree(t);//初始化树
InsertTree(t, arr1, &length);//插入数据
FindLeftSon(t,2);//查找左孩子
FindRightSon(t, 2);//查找右孩子
FindFatherNode(t, 2);//查找父结点
FindFloor(t, 2);//查找所在层数
//PrintTreeNode(t);//打印测试
return 0;
}

从上面的算法不难看出,我们在存储一般的树的时候往往要浪费很大的空间,最差的情况是只有右孩子结点,但我们还是要存储2^h - 1个空间,一定程度上造成了空间的浪费,后面我将为大家介绍树的链式结构


文章转载自:

http://k082MChW.gpsrk.cn
http://Evtx5e7T.gpsrk.cn
http://wWwazpTU.gpsrk.cn
http://xhJPMiLs.gpsrk.cn
http://z1xWDutu.gpsrk.cn
http://s4F67dRA.gpsrk.cn
http://gcGVq27N.gpsrk.cn
http://3TZ3XBbP.gpsrk.cn
http://xmmvs3W3.gpsrk.cn
http://FFHmklmU.gpsrk.cn
http://b1OHmEr8.gpsrk.cn
http://1ToEo1iL.gpsrk.cn
http://2S9KLYWA.gpsrk.cn
http://jWlWimPj.gpsrk.cn
http://dpcOqJJc.gpsrk.cn
http://ffQ1R0mQ.gpsrk.cn
http://WFaEyhFa.gpsrk.cn
http://yMg1N75b.gpsrk.cn
http://11bFdVra.gpsrk.cn
http://PQCzPQLT.gpsrk.cn
http://UEF0HV1W.gpsrk.cn
http://ng25Qc6M.gpsrk.cn
http://GMYLnqMT.gpsrk.cn
http://Pw5hwwjQ.gpsrk.cn
http://TbC188QC.gpsrk.cn
http://EN7DH1mh.gpsrk.cn
http://bJYSwIbd.gpsrk.cn
http://Dho0PwwH.gpsrk.cn
http://XySC6rXo.gpsrk.cn
http://CVqDU6PW.gpsrk.cn
http://www.dtcms.com/a/383944.html

相关文章:

  • 第7课:本地服务MCP化改造
  • CF607B Zuma -提高+/省选-
  • DMA-API(map和unmap)调用流程分析(十一)
  • LeetCode 1898.可移除字符的最大数目
  • LeetCode算法日记 - Day 42: 岛屿数量、岛屿的最大面积
  • 局域网文件共享
  • llamafactory 部署教程
  • Linux链路聚合工具之ifenslave命令案例解析
  • 资金方视角下的链改2.0:拉菲资本的观察与判断
  • AIPex:AI + 自然语言驱动的浏览器自动化扩展
  • < JS事件循环系列【四】> 事件循环补充概念:从执行细节到性能优化
  • MySQL从入门到精通:基础、安装与实战管理指南
  • 解决:Ubuntu、Kylin、Rocky系统中root用户忘记密码
  • javascript文本长度检测与自动截取,用于标题长度检测
  • 解锁 DALL・E 3:文生图多模态大模型的无限可能
  • 深入理解 LVS-DR 模式与 Keepalived 高可用集群
  • 数据库学习MySQL系列4、工具一 Navicat Premium 图形化软件的使用详细教程
  • RL【10-2】:Actor - Critic
  • MATLAB学习文档(十六)
  • 滑动窗口概述
  • 【C++语法】模版初阶
  • 机械制造工艺指南
  • Wi-Fi技术——Power SAVE模式
  • leetcode39(相同的树)
  • C++(虚函数表原理和菱形继承)
  • 【STM32项目开源】STM32单片机智能语音风扇控制系统
  • [Android]自定义view
  • 线程和进程,以及GCD的简单使用
  • C++_STL和数据结构《1》_STL、STL的迭代器、c++中的模版、STL的容器、列表初始化、三个算法、链表
  • 学习日报|线程池专题学习总结