【数据结构】二叉树(下)

简介: 【数据结构】二叉树(下)

二叉树的链式结构

  链式二叉树的增删查改是没有意义的,建立在二叉树基础上的搜索二叉树才具备增删查改的意义。但是链式二叉树是基础,就像修房子得先打地基一样。

二叉树的遍历

首先确定一个概念,二叉树分为空树和非空树,只要是非空树就有根节点、根节点的左子树和根节点的右子树。二叉树的定义是递归式的。

 二叉树遍历是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作依次。访问节点所做的操作依赖于具体的应用问题,遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。

 二叉树一共有四种遍历方式,前序遍历(先根遍历)、中序遍历(中根遍历)、后序遍历(后根遍历)和层序遍历。

前序遍历(先根遍历)

  访问根节点的操作发生在遍历其左右子树之前。在遍历时,会不断向下遍历知道遇到空树才停止。

e1f4f9d7bb084fe0ad9c1831613818ea.png

void PrevOrder(BTNode* root)
{
  if (NULL == root)
  {
    printf("NULL ");
    return;
  }
  printf("%d ", root->data);
  PrevOrder(root->left);
  PrevOrder(root->right);
}

 栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->深蓝色->粉色->金色->紫色->青色。

fac4d8cc7ab74c8d83533721b8c265b2.png

中序遍历(中根遍历)

  访问根节点的操作放生在遍历其左右子树之间。


54d3e49e32f24fc7bd84da91c8007999.png

void InOrder(BTNode* root)
{
  if (NULL == root)
  {
    printf("NULL ");
    return;
  }
  InOrder(root->left);
  printf("%d ", root->data);
  InOrder(root->right);
}

 栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->蓝色->粉色->深蓝色->金色->青色->紫色。

21f06f17eab043c1a343477ab376358f.png

后序遍历(后根遍历)

  访问根节点的操作发生在遍历其左右子树之后。


0119b0dcafce4d18b03596d1ea8e3531.png

void PostOrder(BTNode* root)
{
  if (NULL == root)
  {
    printf("NULL ");
    return;
  }
  PostOrder(root->left);
  PostOrder(root->right);
  printf("%d ", root->data);
}

栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->蓝色->粉色->深蓝色->金色->青色->紫色。

191cd7c525864c9e8679877f528d9557.png

层序遍历

  从第一层开始,每层从左到右,一层一层的走。四种遍历中,只有层序遍历是非递归的,它采用的是队列来实现的。


47942d6a2ab240d4a502825e8182c565.png

void LevelOrder(BTNode* root)
{
  Queue q;
  QueueInit(&q);
  // 先将根节点存入队列
  if (root)
    QueuePush(&q, root);
  // 判空,如果为空就不执行以下语句
  while (!QueueEmpty(&q))
  {
    // 获取队头,打印之后,移出队列
    BTNode* front = QueueFront(&q);
    printf("%d ", front->data);
    QueuePop(&q);
    if (front->left)
      QueuePush(&q, front->left);
    if (front->right)
      QueuePush(&q, front->right);
  }
  printf("\n");
  QueueDestroy(&q);
}

83f48b87f2764dd09e0640666011e996.png

二叉树的构建

  二叉树的构建根据三种递归的遍历方式进行构建,可以进行前序、中序、后序构建,我这里使用的是前序构建。

BTNode* CreatBinaryTree(BTDataType* a, int* pi)
{
  if (-1 == a[*pi])
  {
    (*pi)++;
    return NULL;
  }
  BTNode* root = (BTNode*)malloc(sizeof(BTNode));
  if (NULL == root)
  {
    perror("malloc fail");
    exit(-1);
  }
  root->data = a[(*pi)++];
  root->left = CreatBinaryTree(a, pi);
  root->right = CreatBinaryTree(a, pi);
  return root;
}

二叉树的节点数

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

栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->蓝色->粉色->深蓝色->金色->青色->紫色,最后返回的值是6。


913941f2678f4c268518b6f655bd5491.png

二叉树的叶子数

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


栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->蓝色->粉色->深蓝色->金色,最后结果为3。


21c8b0f8e63c4445a55c3419bde33210.png

二叉树的高度

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

栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->蓝色->粉色->深蓝色->金色,最后结果为3。

32112009a06e460bb5c7b156f490e555.png


二叉树K层节点数

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

栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->蓝色->粉色->深蓝色->金色,最后结果为3。


3ee00ac59d1f4ce388891799aea8824c.png

查找值为X的节点

BTNode* TreeFind(BTNode* root, BTDataType x)
{
  if (NULL == root)
    return NULL;
  if (x == root->data)
    return root;
  BTNode* ret1 = TreeFind(root->left, x);
  if (ret1)
    return ret1;
  BTNode* ret2 = TreeFind(root->right, x);
  if (ret2)
    return ret2;
  return NULL;
}

栈帧空间的创建销毁顺序按照下图进行的,向右的箭头表示创建,向左的箭头表示销毁。创建销毁的顺序是橙色->绿色->蓝色->粉色->深蓝色->金色,最后结果为数字5节点的地址

d3c96c360e2f44a79e40fa41312bc161.png

判断二叉树是否为完全二叉树

bool TreeComplete(BTNode* root)
{
  Queue q;
  QueueInit(&q);
  if (root)
    QueuePush(&q, root);
  // 若队列为空,则不执行
  while (!QueueEmpty(&q))
  {
    BTNode* front = QueueFront(&q);
    QueuePop(&q);
    // 判断front是否为空,为空则跳出循环
    if (!front)
    {
      break;
    }
    else
    {
      QueuePush(&q, front->left);
      QueuePush(&q, front->right);
    }
  }
  // 若队列为空,则不执行
  while (!QueueEmpty(&q))
  {
    BTNode* front = QueueFront(&q);
    QueuePop(&q);
    if (front)
    {
      QueueDestroy(&q);
      return false;
    }
  }
  QueueDestroy(&q);
  return true;
}

二叉树的销毁

// 二叉树销毁
void TreeDestory(BTNode* root)
{
  if (NULL == root)
  {
    return;
  }
  TreeDestory(root->left);
  TreeDestory(root->right);
  free(root);
}
目录
相关文章
|
9天前
|
存储 算法 Java
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
42 9
 算法系列之数据结构-二叉树
|
2月前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
61 12
|
2月前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
60 10
|
2月前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
61 2
|
3月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
4月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
140 4
|
4月前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
246 8
|
5月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
48 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
5月前
|
存储 算法 搜索推荐
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
这篇文章主要介绍了顺序存储二叉树和线索化二叉树的概念、特点、实现方式以及应用场景。
72 0
数据结构与算法学习十七:顺序储存二叉树、线索化二叉树
|
5月前
|
Java
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
【用Java学习数据结构系列】震惊,二叉树原来是要这么学习的(二)
50 1