手撕基础二叉树:从链式存储到层序遍历,彻底搞懂所有核心接口

二叉树基础全解:存储方式、遍历原理与查找树对比 本文全面介绍了二叉树的基本概念、存储方式、遍历方法及其与查找树、散列表的对比。主要内容包括:1. 树与二叉树的定义及分类(满二叉树、完全二叉树);2. 链式与数组两种存储方式的优缺点;3. 递归遍历和层序遍历的实现及复杂度分析;4. 二叉查找树的操作原理及其性能特点;5. 树结构与散列表的对比,突出二叉树在有序操作、范围查询等方面的优势;6. 处理重复数据的方法和树高计算技巧。文章强调二叉树在算法和工程中的重要性,为面试和实际应用提供基础知识框架。 阅读详情

手撕基础二叉树:从链式存储到层序遍历,彻底搞懂二叉树所有核心接口

二叉树不仅在数据结构中举足轻重,同时也在算法的学习中至关重要(例如搜索算法 BFS,DFS),今天带大家一起学习二叉树这个硬骨头。

学完本篇文章你能获得什么样的新知识或者新的观点?

  1. 递归的再一步加深理解
  2. 链式存储的结构
  3. 广度优先搜索BFS,深度优先搜索DFS,层序遍历
  4. 六个统计接口,完全二叉树的判断
  • 注:学习本章需要具备 C 语言的基本语法,树与链表,队列的简单概念

二叉树的链式存储

A.二叉树是什么?

二叉树是一种树形结构里的特殊结构,一棵二叉树由左子树➕右子树➕根节点构成,同时它的左子树和右子树,本身又是一棵二叉树,这就奠定了它递归的重要原理。同时树也可以为空树。
同时,二叉树分为普通二叉树,完全二叉树,完全二叉树是指除了最后一层外,所有节点是满的,但最后一层可以不满,但从左到右必须连续,满二叉树,满二叉树是指每一层的节点都为满节点的二叉树,满二叉树是一种特殊的完全二叉树,当一棵树为完全二叉树时,我们就可以用数组来存储,也就是堆 ,详见可以看下面内容。
这个在这里插入图片描述
由此,我们就可以用代码来定义一棵二叉树与创建一棵二叉树(注:二叉树有链式存储与数组存储,展现二叉树的特殊递归性质,接下来用链式存储)

typedef int DataType;
typedef struct Node
{
 struct Node* left; // 左孩子孩子结点
 struct Node* right; // 右孩子节点
 DataType data; // 结点中的数据
}Treenode;
Treenode * BuyNode(BTDataType x)
{
  Treenode * NODE =  (Treenode*)malloc(sizeof(Treenode));
  if (NODE == NULL)
  {
    perror("malloc fail");
    exit(1);
  }
  NODE->data = x;
  NODE->left = NODE->right = NULL;
  return NODE;
}

Treenode * CreatBinaryTree()
{
  Treenode* node1 = BuyNode(1);
  Treenode* node2 = BuyNode(2);
  Treenode* node3 = BuyNode(3);
  Treenode* node4 = BuyNode(4);
  Treenode* node5 = BuyNode(5);
  Treenode* node6 = BuyNode(6);
  node1->left = node2;
  node1->right = node4;
  node2->left = node3;
  node4->left = node5;
  node4->right = node6;

  return node1;
}

当我们创建好之后,这棵树的样子就是这样

		1
       / \
      2   4
     /   / \
    3   5   6

B.二叉树的深度优先遍历

二叉树与顺序表,链表,队列,栈等线性数据结构不同,那我们该怎样遍历一棵二叉树呢?上面的介绍就埋下了这个伏笔,二叉树的左子树与右子树都是一棵新的二叉树这个性质至关重要。

a.前序遍历

在二叉树中,通常有三种遍历方式,分别为前序遍历,中序遍历,后序遍历,这里的前中后都是指的根节点,例如前序为—根节点,左孩子,右孩子,中序就是左根右,后序则是左右根。我们重点讲前序遍历

void * PreOrder(Treenode * root)
{
  if (root == NULL)
  {
   	printf("N ");
    return;
  }
  printf("%d ",root->data);
  PreOrder(root->left);
  PreOrder(root->right);
}
  • 此代码核心逻辑为:二叉树也可以是一棵空树,而当遍历到一棵空树时,说明我们走到了叶子节点,此时我们就返回到它的父亲,如果它不是空树,我们需要访问它自己,也就是根节点,此时再先以左孩子为根节点去递归,后再用右孩子为根节点去递归遍历
PreOrder(1)          → 打印1
  PreOrder(2)        → 打印2
    PreOrder(3)      → 打印3
      PreOrder(NULL) → 打印N,返回
      PreOrder(NULL) → 打印N,返回
    PreOrder(NULL)   → 打印N,返回
  PreOrder(4)        → 打印4
    PreOrder(5)      → 打印5
    ...

以上就是代码的递归过程,需要特别提示的是

  • 焚决:当我们看着递归的代码时,需要看到函数的所有代码,然后我们试想最特殊的情况,例如空树,发现它也能完成工作,再从特殊到了一般,所以,递归不需要在脑子里模拟全过程,只需要相信每一个子调用都能正确完成它的工作。这句话对使用和理解递归非常的关建,它关系到我们后面的所有代码
b.中序遍历与后序遍历

中序遍历与后序遍历的本质依旧是利用递归,只不过访问根节点的时机不同,所以遍历的结构也会不同,这里就不做代码演示了,直接给出不同遍历的不同结果

前序:1 2 3 N N N 4 5 N N 6 N N
中序:N 3 N 2 N 1 N 5 N 4 N 6 N
后序:N N 3 N 2 N N 5 N N 6 4 1

C.二叉树的六个统计接口

Treesize()         // 节点总数
TreeleafSize()     // 叶子节点数  
TreeHeight()         // 树的高度
TreeLevelKsize()   // 第k层节点数
TreeFind()         // 查找节点
TreeDestroy()      // 销毁

处理所有的二叉树问题,分治的思想至关重要,始终想清楚二叉树的性质与结构,左子树➕右子树➕根节点

a.Treesize()

节点总数 = 左子树 + 右子树 + 根节点

int Treesize(Treenode * root)
{
    return root == NULL ? 0 : Treesize(root->left)
    						+Treesize(root->right)+1;
}
b.Treeleafsize()

叶子节点,左右都为 NULL 返回 1,否则递归求和

int Treeleafsize(Treenode * root)
{
    if(root == NULL)    return 0;

    if(root->left == NULL && root->right == NULL)   return 1;

    return Treeleafsize(root->left) + Treeleafsize(root->right);
}
c.TreeHeight()

树的高度,是左右子树高的那一棵再加 1

int TreeHeight(Treenode * root)
{
    if(root == NULL)    return 0;

    int left = TreeHeight(root->left);
    int right = TreeHeight(root->right);

    return left > right ? left +1 : right+1;
}
d.TreeLevelKsize()

第k层 = 左子树第k-1层 + 右子树第k-1层

int TreeLevelKsize(Treenode * root,int k)
{
    if(root == NULL)   return 0;
    
    //遇到了该第 k 层,递归到了这一
    if(k == 1)  return 1;
    
    //第一层的第 k 层,是子树的k-1 层
    return TreeLevelKsize(root->left,k-1) + TreeLevelKsize(root->right,k-1);
}
e.TreeFind()

先在左子树里找,找到之后就返回,找不到就去右子树

Treenode * TreeFind(Treenode * root,BTDataType x)
{
    if(root == NULL)    return NULL;

    if(root->data == x)  return root;

    Treenode * left = TreeFind(root->left,x);
    //判断优化性能
    if(left != NULL)
    return left;

    return TreeFind(root->right,x);
}
f.TreeDestroy()

先删孩子再删节点,后序遍历

void TreeDestroy(Treenode * root)
{
    if(root == NULL)    return ;
    TreeDestroy(root->left); 
    TreeDestroy(root->right);
    free(root);
}

C.二叉树的层序遍历

二叉树的层序遍历,与前中后序遍历不同的是,它并不依靠递归遍历,因为我们需要一层一层的去访问二叉树的元素,而递归遍历天然是一种深度遍历,不能达到我们的目的。

a.那我们该怎样实现一个层序遍历呢?

依靠队列这个数据结构,我们能很好的实现层序遍历,想想一下,一个根节点它如果有左孩子和右孩子,我们入队列,而当它出队列的时候,我们将它的左孩子和右孩子再入队列,如此循环,我们便能很方便的实现层序遍历。
但由于 C 语言没有队列的容器,没有像 C++那样的 queue,所以我们需要自己手动实现 i 一个队列

//将队列的元素类型调整为二叉树节点的指针
typedef struct BinaryTreeNode * QDatatype;
typedef struct QueueNode
{
  QDatatype data;
  struct QueueNode * next;
}QNode;

//将整个队列用头节点和尾节点管理
typedef struct Queue
{
  QNode * phead;
  QNode * ptail;
  int size;
}Que;
//队列的初始化
void QueInit(Que * pq)
{
  assert(pq);
  pq->size = 0;
  pq->phead = pq->ptail = NULL;
}
//尾插
void QuePush(Que * pq,QDatatype x)
{
  //pq是装了头尾节点的结构体,nwenode 是一个节点
  assert(pq);
  QNode * newnode = (QNode *)malloc(sizeof(QNode));
  if (newnode == NULL)
  {
    perror("malloc fail");
    return;
  }
  newnode->next = NULL;
  newnode->data = x;
  if (pq->ptail == NULL)
  {
    pq->phead = pq->ptail = newnode;
  }
  else
  {
    pq->ptail->next = newnode;
    pq->ptail = newnode;
  }
   pq->size++;
}
//头删
void QuePop(Que * pq)
{
  assert(pq);
  assert(pq->size != 0);

  if (pq->phead->next == NULL)
  {
    free(pq->phead);
    pq->phead = pq->ptail = NULL;
  }
  else
  {
    QNode * next = pq->phead->next;
    free(pq->phead);
    pq->phead = next;
  }
  pq->size--;
}
//取队头
QDatatype QueFront(Que * pq)
{
  assert(pq);
  assert(pq->phead);
  return pq->phead->data;
}

//取队尾
QDatatype QueBack(Que *pq)
{
  assert(pq);
  assert(pq->ptail);
  return pq->ptail->data;
}

//判空
bool QueEmpty(Que* pq)
{
  assert(pq);
  return pq->size == 0;
}

//销毁
void QueDestroy(Que * pq)
{
  assert(pq);
  QNode * cur = pq->phead;
  while (cur)
  {
    QNode * next = cur->next;
    free(cur);
    cur = next;
  }
  pq->phead = pq->ptail = NULL;
  pq->size = 0;
}

我们模拟整个层序遍历的过程

初始入队:[1]

出1,打印1,左孩子2和右孩子4入队:[2, 4]
出2,打印2,左孩子3入队(右为NULL不入):[4, 3]  
出4,打印4,左孩子5和右孩子6入队:[3, 5, 6]
出3,打印3,无孩子:[5, 6]
出5,打印5:[6]
出6,打印6:[]

再根据整个过程很容易的将代码写出

//层序遍历
void TreeLevelOrder(Treenode * root)
{
  Que q;
  QueInit(&q);
  if (root)
    QuePush(&q,root);
  while (!QueEmpty(&q))
  {
    Treenode * front = QueFront(&q);
    QuePop(&q);

    printf("%d ",front->data);

    if (front->left)
      QuePush(&q,front->left);
    if (front->right)
      QuePush(&q,front->right);
  }
  QueDestroy(&q);
}
b.层序遍历的重要作用

通过层序遍历,我们可以实现一个重要作用,用来判断一棵树是否为完全二叉树,完全二叉树的定义是前 k-1 层是满层结构,而最后一层可以不满,但必须连续,所以我们需要解决的问题是,怎么用代码检测中间有没有空洞?
我们的核心思路就是:把空也入队列,让我们检测第一次层序遍历二叉树,遇到空,那就 break,说明后面不应该有节点了,如果后面还有节点,那么这中间就有个空洞,不是完全二叉树,而在第二阶段,检查队列里是否还有节点
在这里插入图片描述
接下来,我们顺着思路,将代码轻松写出


bool CompleteTree(Treenode * root)
{
  Que q;
  QueInit(&q);
  if (root)
    QuePush(&q,root);

  while (!QueEmpty(&q))
  {
    Treenode * front = QueFront(&q);
    QuePop(&q);
    if (front == NULL)
      break;
    QuePush(&q,front->left);
    QuePush(&q,front->right);
  }

  while (!QueEmpty(&q))
  {
    Treenode * front = QueFront(&q);
    QuePop(&q);

    if (front)
    {
      QueDestroy(&q);
      return false;
    }
  }
  QueDestroy(&q);
  return true;
}

二叉树的链式存储各接口的总结

在这里插入图片描述
为什么空间复杂度都是O(N)?
递归调用会压栈,最坏情况下树退化成链表,递归深度为N,所以栈空间是O(N)。层序遍历的空间消耗在队列上,最坏情况队列存满一层,也是O(N)。
有没有O(1)空间的?
严格来说没有,递归本身就有栈开销。如果面试问到,可以说"不计递归栈空间的话是O(1)"。
层序遍历和完全二叉树判断有什么不同?
时间复杂度一样都是O(N),但完全二叉树判断的队列会把NULL也压进去,常数项略大。

以上就是关于基础二叉树的所有重要知识,如果你能看到这里,我相信你一定有很深的体会和长足的进步!

流水不争先,争滔滔不绝

LVGL v8.3 图片显示与解码缓存实战:PNG 上屏、C 数组与文件双方案 LVGL v8.3 图片两种存储方式、PNG/JPG 上屏解码器挂载、LV_IMG_CACHE_DEF_SIZE 缓存调优、手动预解码头像有效性判断,及"缓存被动画清空"真实踩坑。 阅读详情

相关推荐

帆软FineBI考试题

Flint 补录表,有批次删除功能。在分析主题内添加数据时能够选择批量添加数据。插件安装过程中有报错提示需要下载 Fine I for Excel 运行环境进行修复,修复完毕后重新安装插件。图例显示支持自定义设置,且图例标题支持隐藏显示。finebi中的指标如果想进行维度区间/真的自定义分组,不能直接拖拽到组建区域中需要先转化为维度方可进行指标分组。excel报表不支持分页。

Davina_yu的博客 1603

链式存储范式下的二叉树:基础操作实现解析

二叉树是数据结构中的基础核心结构,其操作覆盖创建、遍历、属性统计、结构判断等关键场景。本文围绕二叉树的。

2402_86350387的博客 809

手把手教你用神经网络优化电机控制:从Simulink仿真到实际部署

本文提供了一套完整的工程实践指南,详细讲解了如何将神经网络应用于电机控制,从Simulink仿真建模、轻量级网络设计,到关键的模型量化与代码生成,最终实现向DSP/FPGA硬件的实际部署。文章直面实时性、精度与资源限制等核心工程挑战,为工程师提供了从理论到落地的清晰路径和实用避坑策略。

weixin_29246195的博客 226

【数据结构-初阶】二叉树---链式存储

🎈🔥个人专栏🌟上期回顾:在上一篇文章中,我们对二叉树的顺序存储结构进行了详细的学习,知道了二叉树的顺序存储结构方式是---也就是以堆的方式进行存储,那么我们想着,既然有顺序存储结构,那有没有链式的存储结构呢?答案是,有的兄弟,有的,那么这篇文章我们就来讲讲,二叉树的链式存储结构。

2501_91249865的博客 1116

手把手教学,Python 游戏编程之实现飞机大战(含源代码)

我想大家都是有玩过类似飞机大战的射击类游戏,也享受目标被消除通过后带来的愉悦感。那么如果用Python来实现飞机大战游戏?下面就跟大家一起用Python来做一个小游戏,不仅可以从中感受到乐趣,还可以提升自己的能力。

veratata的博客 1万+

金三银四!风控建模岗面试题库大全:从理论到实战避坑指南

风控建模面试大全

阿黎逸阳的博客 767

【手撕数据结构】链式二叉树

所以当k=1的时候,是第k层,第k层节点个数实际就是第k-1层的左右孩子节点个数,求k-1层节点的左右孩子节点即可。📚当k > 1 时,第k层的结点个数为第k - 1层左孩子节点个数 + k-1层右孩子的结点个数。除了判断k之外,别忘了每次都要判断一下传进来的根结点是否为空,防止访问。规则:二叉树高度 = 左子树和右子树中高度大的那个 + 1。📚当k == 1时,return 1。规则:左子树——右子树——根。

apple_61439616的博客 1166

R语言做一个 GM (1,1)灰色预测模型

累加生成是GM(1,1)模型的另一个重要步骤,它通过构造累加生成序列,把非线性非平稳时间序列转化为线性平稳时间序列。GM(1,1)是一种基于灰色系统理论的预测模型,通常用于中小样本的非线性、非平稳时间序列数据分析。灰色预测模型的核心是灰度处理,将原始时间序列转化为灰色时间序列。这里使用R语言中的diff函数对时间序列进行一次差分,然后对结果取累加和得到灰度序列。以上是GM(1,1)灰色预测模型在R语言中的实现步骤。需要注意的是,GM(1,1)模型适用于中小样本的时间序列预测,对于长期预测效果可能较差。

Mrrunsen的博客 3842

【数据结构】二叉树链式结构——感受递归的暴力美学

查找相对来说就比较简单了,遍历二叉树,为空就返回NULL,值为x就返回该节点的地址,如果遍历过程中函数返回值不为NULL,就证明找到了,直接返回即可。访问4这个节点的右子树,也为空,此时节4这个点为根节点的左子树已经访问 结束了,回退到其父节点的函数栈帧,访问其父节点的右子树。这里,3这个节点的左右节点都为空,访问就直接返回,回退到根节点,就说明根节点的右子树访问已经结束,此时二叉树已经变了结束。再访问根节点5的左子树。遍历二叉树,遍历到空节点就返回0,不是空节点就返回其左子树和右子树节点个数之和再加一。

LH__1314的博客 4366

亚马逊跨境电商选品数据分析:Python爬虫实战指南

本文将带领大家构建一套完整的亚马逊选品数据采集与分析系统,使用最新的Python技术栈,从零开始爬取亚马逊商品数据,并进行深度分析。

2201_76125261的博客 299

matlab 一维相位解缠

一维相位解缠算法的matlab代码实现。

点云侠的博客 372

[Java]快速入门二叉树,手撕相关面试题

本文主要讲解二叉树重点知识很少涉及无关的背景知识,旨在即快速又清晰熟练掌握二叉树并手撕相关面试题,希望我的文章能对你有所帮助与启发.

Node_Hao的博客 1413

YOLOv11改进前必看 - YAML模型配置文件详细解读(再也不用担心通道数不匹配) 附网络结构图

YOLOv11的模型配置文件在中,里面包含以及,本文以目标检测模型文件为例(其他文件完全一致),详细介绍一下YOLOv11模型文件中各参数的含义。

Limiiiing的博客 5311

二叉树(链式存储)基本操作

二叉树链式存储基本操作C/C++实现代码加运行结果(包括二叉树的创建,前序,中序,后序,层序遍历)

gaokuiyuan的博客 2472

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

对于数据结构:链式二叉树的超详细保姆级解析—下

本文系统讲解了链式二叉树的实现与应用。主要内容包括:1. 二叉树的链式存储结构,通过节点指针实现树的连接;2. 三种深度优先遍历(前序、中序、后序)的递归实现与应用场景;3. 层序遍历的队列实现及其应用;4. 二叉树常见操作如查找节点、统计节点数、计算深度等;5. 判断完全二叉树的方法与内存管理要点。文章通过生活化类比和代码示例,详细解析了递归思想在二叉树操作中的应用,并强调了销毁二叉树时后序遍历的重要性,为学习更复杂的树结构奠定了基础。

2503_92929084的博客 1802

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

从零开始学二叉树(下):链式二叉树与递归的终极修炼

一句话预告:递归不是魔法,而是“分而治之”的思维艺术;遍历不是背代码,而是模拟计算机的思考路径。

dongaoran的博客 6210

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【数据结构】二叉树进阶:层序遍历不仅是按层打印,更是形态判定的利器!

本文深入探讨了二叉树广度优先搜索(BFS)的核心实现,详细解析了如何利用“先进先出”的链式队列实现层序遍历。通过对比深度优先遍历(DFS)的纵向特性,揭示了层序遍历在处理树形态判定问题上的独特优势。文章重点分析了判定完全二叉树的底层逻辑,批判性地指出了仅依赖“节点总数”或“高度差”等传统思路的局限性,并创造性地提出了利用 NULL 节点入队的“连续性检测”算法,为二叉树形态校验提供了严谨的工程实践参考。

Extreme35的博客 1295

【数据结构】树与二叉树全解析:从概念到堆排序与链式存储实战

本文介绍了树和二叉树的基本概念及相关性质。首先阐述了树的结构特点与相关术语,包括度、层次、路径等概念。重点讲解了二叉树的特性、分类(满二叉树和完全二叉树)以及5条重要性质。文章还详细介绍了二叉树的顺序存储结构,并以堆的实现为例,展示了初始化、插入、删除等操作的代码实现,包括向上调整和向下调整算法。最后给出了测试代码的运行结果,验证了堆的基本功能实现。全文通过图文并茂的方式,系统性地讲解了树和二叉树这一非线性数据结构的基础知识。

2402_87037360的博客 1053

【数据结构】一文看懂二叉树的存储与遍历

就能够避免这种循环。而这种后入后出(迟到早退(bushi)的原则符合栈的特性。所以这里我们设立一个栈,将访问过的所有节点按次序入栈,

Tryagein的博客 2222

【数据结构】二叉树②-链式二叉树

本文介绍了二叉树的链式存储实现方法,包括二叉链表结构体定义和基本操作函数。重点讲解了三种递归遍历方式(前序、中序、后序)的实现原理,以及节点统计、查找、销毁等递归函数的编写。通过队列辅助实现了层序遍历和完全二叉树判断。最后对比分析了数组存储(堆式结构)和链式存储的优缺点:数组存储适合完全二叉树,访问高效但空间利用率低;链式存储灵活支持任意树形,指针操作方便但存在空间开销。文章配有详细代码示例和执行过程分析,帮助理解二叉树链式存储的实现机制。

Kaisir777的博客 1196

数据结构初阶:详解二叉树(三):链式二叉树

本文详细介绍了链式结构二叉树的实现方法,主要包括:1. 二叉树的链式结构定义与手动创建方法;2. 前序、中序、后序三种递归遍历的实现及递归过程分析;3. 二叉树基本操作的实现,包括:计算结点个数/叶子节点个数/第k层结点个数、求二叉树深度、查找指定值结点、销毁二叉树等;4. 层序遍历的实现及队列辅助结构的应用;5. 完全二叉树的判断方法。文章通过大量代码示例和递归过程演示,系统讲解了二叉树的各种操作实现原理,并提供了完整的实现代码。这些内容为学习二叉树这一重要数据结构提供了详实的实践指导。

2302_80761497的博客 1285

数据结构:二叉树(链式结构)

主要介绍了二叉树的链式结构,还有创建二叉树和二叉树相关功能的详细说明和代码实现,最后附带源码

2301_79601095的博客 1754

深入解析二叉树链式存储结构

本文深入探讨了二叉树的链式存储结构实现。首先介绍了二叉链表节点的定义,包含数据域和左右孩子指针。随后详细讲解了核心操作的实现:包括节点初始化、递归创建二叉树、计算树的高度、统计非空节点数、查找叶子节点数、获取第K层节点数以及查找指定节点等。重点分析了二叉树的四种遍历方式(前序、中序、后序和层序遍历),其中层序遍历需借助队列实现。文章还提供了快速创建二叉树的示例代码,并通过图示说明各种操作的执行过程。相比顺序存储,链式存储能更灵活地表示树形结构,尤其适合处理非完全二叉树的情况。

2301_77631043的博客 632

一文搞懂什么是二叉树(二叉树的种类、遍历方式、定义)

刚刚我们说过了二叉树有两种存储方式顺序存储,和链式存储,顺序存储就是用数组来存,这个定义没啥可说的,我们来看看链式存储的二叉树节点的定义方式。intval;};大家会发现二叉树的定义和链表是差不多的,相对于链表,二叉树的节点里多了一个指针,有两个指针,指向左右孩子。这里要提醒大家要注意二叉树节点定义的书写方式。在现场面试的时候面试官可能要求手写代码,所以数据结构的定义以及简单逻辑的代码一定要锻炼白纸写出来。二叉树是一种基础数据结构,在算法面试中都是常客,也是众多数据结构的基石。...

w20001118的博客 2286

二叉树:从树的概念及递归思维到链式二叉树代码实现,一篇讲透

这篇文章全面介绍了二叉树的基本概念、性质及特殊类型,为后续链式二叉树的实现奠定理论基础。 摘要要点: 树的基本概念与递归特性:明确定义树结构,强调其递归本质,分析节点间关系与属性(度、层次、高度等) 二叉树核心知识: 定义:每个节点最多两棵子树的有序树结构 特殊类型:满二叉树(每层节点数最大)、完全二叉树(最后一层连续排列) 重要性质:包括节点数量与高度的关系、叶子节点与度为2节点的数量关系 数学推导:通过等比数列公式计算不同树型的最大节点数,证明关键性质 文章采用图文结合方式,包含大量示例图和公式推导,适

2401_82359002的博客 606

链式二叉树的实现

链式二叉树的实现

2302_76314368的博客 1528
上一篇: 纯干货C++STL 在算法比赛中的常见应用与技巧——String 篇
下一篇: 七大排序算法全解析:从插入到三路快排,手把手带你掌握核心思想与实战陷阱
DDXYcoder
博客等级 码龄1年 140粉丝 29原创
评论 17
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值