二叉树的讲解

简介: 1.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1) 个结点.2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是 2^h-1.3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为02 ,则有n0 =n2 +14. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= . (ps: 是log以2为底,n+1为对数)5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

二叉树的性质

1.若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有2^(i-1) 个结点.

2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是 2^h-1.

3. 对任何一棵二叉树, 如果度为0其叶结点个数为n0 , 度为2的分支结点个数为02 ,则有n0 =n2 +1

4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= . (ps: 是log以2为底,n+1为对数)

5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:

  1. 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
  2. 若2i+1=n否则无左孩子
  3. 若2i+2=n否则无右孩子


二叉树的链式结构

一般来说,二叉树分为二叉链和三叉链,二叉链就是结构里面一个左孩子节点,一个右孩子节点,三叉链多了一个父亲节点,我们比较经常见的都是二叉链的,所以我们主要讲的也是二叉链。


结构:

typedef int BTDataType;
typedef struct BinaryTreeNode
{
  BTDataType data;
  struct BinaryTreeNode* left;
  struct BinaryTreeNode* right;
}BTNode;

我们在看任意一颗二叉树时,都可以将它分为三部分,根,左子树,右子树,左子树也可看成根,左子树,右子树,右子树也可看成根,左子树,右子树,因此二叉树定义是递归式的,我们后面的代码也是主要靠递归来实现的。


二叉树的遍历

二叉树遍历(Traversal)是按照某种特定的规则,依次对二叉树中的节点进行相应的操作,并且每个节点只操作一次。


二叉树的遍历分为,前序遍历、中序遍历、后序遍历、层序遍历,其中前中后序遍历是递归定义的,而层序遍历是非递归遍历的。


前序遍历

前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右子树之前。前序先访问根节点,再访问左子树,再访问右子树。

e4a3bad1d7e0454d9d6ff57903a1c851.png

代码如下:

// 二叉树前序遍历 
void BinaryTreePrevOrder(BTNode* root)
{
  if (root == NULL)
  {
    return;
  }
  printf("%d ", root->data);
  BinaryTreePrevOrder(root->left);
  BinaryTreePrevOrder(root->right);
}

递归图:

b609c6e9685144b09de172bb2c02aca2.png

大家可以根据这个递归展开图好好理解一下,后面的二叉树基本操作都是需要用递归来实现的。


中序遍历

中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。


代码如下:

// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root)
{
  if (root == NULL)
  {
    return;
  }
  BinaryTreeInOrder(root->left);
  printf("%d ", root->data);
  BinaryTreeInOrder(root->right);
}

后序遍历

后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。


代码如下:

// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root)
{
  if (root == NULL)
  {
    return;
  }
  BinaryTreePostOrder(root->left);
  BinaryTreePostOrder(root->right);
  printf("%d ", root->data);
}

这三种遍历本质上都是一样的,理解清楚一个,另外两个就很简单了。


层序遍历

层序遍历和其他三种都不一样,设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

00eef2f7d0f8404ebf9e284163d468ff.png

那这个要怎么实现呢?

我们需要借助我们的队列,我们可以先把根节点入到队列里,然后开始出队列,只不过每次出的时候如果它的左孩子不为空就将左孩子入队列,右孩子不为空就将右孩子入队列,以此类推。我们就是利用了队列的先进先出,我们就可以轻松地完成层序遍历。


代码如下:

// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
  Queue q;
  QueueInit(&q);
  if (root)
  {
    QueuePush(&q,root);
  }
  while (!QueueEmpty(&q))
  {
    BTNode* front = QueueFront(&q);
    QueuePop(&q);
    if (front->left)
    {
      QueuePush(&q, front->left);
    }
    if (front->right)
    {
      QueuePush(&q, front->right);
    }
    printf("%d ", front->data);
  }
  printf("\n");
}

二叉树的销毁

二叉树的销毁很简单,我们需要遍历一遍二叉树,但是我们用那种遍历呢,如果用前序,那么就会销毁根节点,就找不到它的左孩子和右孩子,明显是不合适的,最好的情况就是我们先去销毁它的左孩子,再去销毁他的右孩子,然后再销毁根节点,所以这里我们使用后序遍历是比较合适的。


代码如下:

// 二叉树销毁
void BinaryTreeDestory(BTNode* root)
{
  if (root == NULL)
  {
    return;
  }
  BinaryTreeDestory(root->left);
  BinaryTreeDestory(root->right);
  free(root);
}

二叉树的查找

二叉树的查找的基本思路也是遍历一遍二叉树,但是我们需要返回这个节点,这就给我们的难度增加了很多,我们这里想的是先看根节点是不是,如果不是就去他的左子树找,如果找到了就返回,否则就去它的右子树找,找到就返回该节点,最后都找不到我们就返回NULL.


代码如下:

// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
  if (root == NULL)
  {
    return NULL;
  }
  if (root->data == x)
  {
    return root;
  }
  BTNode* left = BinaryTreeFind(root->left, x);
  if (left != NULL)
  {
    return left;
  }
  BTNode* right = BinaryTreeFind(root->right, x);
  if (right != NULL)
  {
    return right;
  }
  return NULL;
}

最后带大家看一下会给我们带来好运的树:

58ffdab93d084b6580cabc9c28091de2.png

今天的分享就到这里,感谢大家的关注和支持!

相关文章
|
9月前
|
算法 前端开发
2583. 二叉树中的第 K 大层和
2583. 二叉树中的第 K 大层和
65 0
|
C语言
【二叉树】的实现
【二叉树】的实现
45 0
|
9天前
|
人工智能 vr&ar DataX
二叉树
本文介绍了树和二叉树的基本概念、表示方法及其应用。首先,树是一种非线性结构,通过根节点展开,常用孩子兄弟表示法实现。接着,二叉树作为特殊的树,每个节点最多有两个子节点,分为不完全、完全和满二叉树。文中还详细讲解了堆的创建与应用,包括小堆和大堆,并展示了堆排序及Top-K问题的解决方法。最后,介绍了二叉树的创建、遍历(前序、中序、后序、层序)及一些常见操作(如查找、计算高度等),并结合LeetCode题目实例,如对称二叉树、子树判断、平衡二叉树和翻转二叉树,深入探讨了二叉树的应用场景和解题思路。
|
9月前
|
存储
|
9月前
|
算法 网络协议 NoSQL
认识二叉树(详细介绍)
认识二叉树(详细介绍)
|
9月前
|
存储 Java C++
二叉树的实现(上)
二叉树的实现
79 0
|
存储
二叉树讲解
二叉树讲解
93 0
【二叉树】(二)
【二叉树】(二)
52 0