数据结构第十三弹---链式二叉树基本操作(上)

简介: 数据结构第十三弹---链式二叉树基本操作(上)


1、结构定义

实现一个数据结构少不了数据的定义,所以第一步需要定义二叉树的机构。

typedef char BTDataType;//定义数据类型,可以根据需要更改
typedef struct BinaryTreeNode
{
  struct BinaryTreeNode* left;//左指针
  struct BinaryTreeNode* right;//右指针
  BTDataType data;//存储数据
}BTNode;

2、手动创建二叉树

初次学习链式二叉树,对于创建一个二叉树较难理解,所以先手动创建二叉树,学习一些操作之后再来通过函数实现链式二叉树。

//创建结点函数
BTNode* BuyTree(BTDataType x)
{
  BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
  newnode->data = x;
  newnode->left = NULL;
  newnode->right = NULL;
  return newnode;
}
//创建结点
  BTNode* A = BuyTree('A');
  BTNode* B = BuyTree('B');
  BTNode* C = BuyTree('C');
  BTNode* D = BuyTree('D');
  BTNode* E = BuyTree('E');
  BTNode* F = BuyTree('F');
//链接结点
  A->left = B;
  A->right = E;
  B->left = C;
  B->right = D;
  E->left = F;

3、前序遍历

前序遍历,又称先根遍历。
遍历顺序:根,左子树,右子树。

代码实现

void PrevOrder(BTNode* root)
{
  if (root == NULL)
  {
    printf("NULL ");
    return;
  }
  printf("%c ", root->data);//根
  PrevOrder(root->left);//左子树
  PrevOrder(root->right);//右子树
}

此处实现的遍历版本是将空指针也打印出来的版本,更适合新手理解

测试

4、中序遍历

中序遍历,又称中根遍历。
遍历顺序:左子树,根,右子树。

代码实现

void InOrder(BTNode* root)
{
  if (root == NULL)
  {
    printf("NULL ");
    return;
  }
  InOrder(root->left);//左子树
  printf("%c ", root->data);//根
  InOrder(root->right);//右子树
}

测试

5、后序遍历

后序遍历,又称后根遍历。
遍历顺序:左子树,右子树,根。

代码实现

void PostOrder(BTNode* root)
{
  if (root == NULL)
  {
    printf("NULL ");
    return;
  }
  PostOrder(root->left);//左子树
  PostOrder(root->right);//右子树
  printf("%c ", root->data);//根
}

测试

6、层序遍历

层序遍历,自上到下,自左到右依次访问数的结点就是层序遍历。

思想(借助一个队列):
1、先将根节点入队,然后开始从队头出数据
2、出队头的数据同时将队头左右子树的结点入队(遇到NULL则不入队)
3、重复第二步,直到队列为空

代码实现

void LevelOrder(BTNode* root)
{
  Queue q;//创建爱你队列
  QueueInit(&q);//初始化队列
  if (root)//根节点不为空则入队
    QueuePush(&q, root);
  while (!QueueEmpty(&q))//队列不为空,循环继续
  {
    BTNode* front = QueueFront(&q);
    QueuePop(&q);//出队
    printf("%c ", front->data);//打印数据
    if (front->left)//如果左子树不为空则入队
      QueuePush(&q, front->left);
    if (front->right)//右子树不为空入队
      QueuePush(&q, front->right);
  }
  QueueDestory(&q);//销毁队列
}

测试

7、计算结点个数

计算结点个数时,可以将问题拆成子问题
1、为空时,结点个数为0
2、不为空时,结点个数=左子树结点个数+右子树结点个数+1(根节点)

代码实现

int TreeSize(BTNode* root)
{
  return root==NULL?0:TreeSize(root->left) + TreeSize(root->right) + 1;
}

测试

8、计算叶子结点个数

计算叶子结点个数时,可以将问题拆成子问题
1、为空时,叶子结点个数为0
2、结点左右孩子为空时,叶子结点个数为1
3、结点不为空,叶子结点个数=左子树叶子结点个数+右子树叶子结点个数

代码实现

int TreeLeafSize(BTNode* root)
{
  if (root == NULL)
  {
    return 0;
  }
  if (root->left == NULL && root->right==NULL)
  {
    return 1;
  }
  return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

测试

9、计算第K层结点个数

计算第K层结点个数时,可以将问题拆分成子问题。
1、为空和非法时,结点个数为0个
2、为第一层时,结点个数为1个
3、不为空且合法时,第K层的结点个数=第K-1层的左子树结点个数+第K-1层的右子树结点个数

代码实现

//第k层结点的个数
int TreeKLevelSize(BTNode* root, int k)
{
  if (k < 1 || root == NULL)//空树或输入k值不合法
    return 0;
  if (k == 1)//第一层结点个数
    return 1;
  //不为空且合法时,第K层的结点个数=第K-1层的左子树结点个数+第K-1层的右子树结点个数
  return TreeKLevelSize(root->left, k - 1) + TreeKLevelSize(root->right, k - 1);
}

测试

10、计算树的最大深度

计算树的最大深度时,可以将问题拆成子问题
1、为空时,深度为0
2、不为空时,最大深度为左子树和右子树较大的深度+1(自己)

代码实现

int maxDepth(BTNode* root) {
  if (root == NULL)
    return 0;//为空,深度为0
  int leftDepth = maxDepth(root->left);//记录左子树最大深度
  int rightDepth = maxDepth(root->right);//记录右子树最大深度
    //不为空时,最大深度为左子树和右子树较大的深度+1(自己)
  return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}

测试

总结

本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

相关文章
|
14天前
|
存储 机器学习/深度学习
【数据结构】二叉树全攻略,从实现到应用详解
本文介绍了树形结构及其重要类型——二叉树。树由若干节点组成,具有层次关系。二叉树每个节点最多有两个子树,分为左子树和右子树。文中详细描述了二叉树的不同类型,如完全二叉树、满二叉树、平衡二叉树及搜索二叉树,并阐述了二叉树的基本性质与存储方式。此外,还介绍了二叉树的实现方法,包括节点定义、遍历方式(前序、中序、后序、层序遍历),并提供了多个示例代码,帮助理解二叉树的基本操作。
38 13
【数据结构】二叉树全攻略,从实现到应用详解
|
11天前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
11天前
|
存储 机器学习/深度学习 C语言
数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
|
11天前
|
存储 C语言
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
|
1月前
|
存储
【初阶数据结构篇】二叉树基础概念
有⼀个特殊的结点,称为根结点,根结点没有前驱结点。
|
1月前
|
算法
【数据结构】树、二叉树与堆(长期维护)(2)
【数据结构】树、二叉树与堆(长期维护)(2)
【数据结构】树、二叉树与堆(长期维护)(2)
|
1月前
|
算法
【初阶数据结构篇】二叉树算法题
二叉树是否对称,即左右子树是否对称.
|
1月前
|
存储
【初阶数据结构篇】实现链式结构二叉树(二叉链)下篇
要改变root指针的指向,将本来指向根节点的root指针改为空,所以传二级指针(一级指针也可以,只不过在调用完记得把root置为空)。
|
1月前
|
存储 测试技术
【初阶数据结构篇】实现链式结构二叉树(二叉链)上篇
先构建根结点,再对左右子树构建,每次需要时申请一个结点空间即可,否则返回空指针。
|
1月前
|
存储 算法 测试技术
【初阶数据结构篇】实现顺序结构二叉树(堆的实现方法)
注意传过去的参数是插入的位置,即插入前的size,在调整完后再将size++