【数据结构】 二叉树的简单理解和代码实现

x33g5p2x  于2021-10-01 转载在 其他  
字(2.5k)|赞(0)|评价(0)|浏览(493)

前言:本章主要介绍二叉树的链式结构,及其前序、中序、后序遍历操作,还有 二叉树的其它基本操作包括求结点个数、求叶子结点个数、求第K层结点个数、求二叉树深度等。

二叉树的链式结构

链式结构实现如下:

  1. typedef char BTDataType;
  2. typedef struct BinaryTreeNode
  3. {
  4. BTDataType data;
  5. struct BinaryTreeNode* right;
  6. struct BinaryTreeNode* left;
  7. }BTNode;

二叉树的遍历方式

前序/中序/后续遍历代码实现

上面已经说到,前序遍历方式为根结点—>左子树—>右子树,我们用下图为例

前序遍历代码:

  1. //二叉树前序遍历
  2. void PreOrder(BTNode* root) {
  3. if (root == NULL) {
  4. printf("NULL ");
  5. return;
  6. }
  7. printf("%c ", root->data);
  8. PreOrder(root->left);
  9. PreOrder(root->right);
  10. }

中序遍历代码:

  1. // 二叉树中序遍历
  2. void InOrder(BTNode* root)
  3. {
  4. if (root == NULL) {
  5. printf("NULL ");
  6. return;
  7. }
  8. InOrder(root->left);
  9. printf("%c ", root->data);
  10. InOrder(root->right);
  11. }

后序遍历代码如下:

  1. // 二叉树后序遍历
  2. void PostOrder(BTNode* root)
  3. {
  4. if (root == NULL) {
  5. printf("NULL ");
  6. return;
  7. }
  8. PostOrder(root->left);
  9. PostOrder(root->right);
  10. printf("%c ", root->data);
  11. }

二叉树的基本操作

求二叉树结点个数

方法一:用全局遍历

  1. 1、全局
  2. int size = 0;//这里不妨思考下能不能直接放入BinaryTreeSize函数内部进行定义
  3. int BinaryTreeSize(BTNode* root)
  4. {
  5. if (root == NULL)
  6. {
  7. return;
  8. }
  9. else
  10. {
  11. ++size;
  12. }
  13. BinaryTreeSize(root->left);
  14. BinaryTreeSize(root->right);
  15. }

方法二:局部变量

  1. 2、遍历 -- 局部变量
  2. void BinaryTreeSize(BTNode* root, int* psize)
  3. {
  4. if (root == NULL)
  5. return;
  6. else
  7. ++(*psize);
  8. BinaryTreeSize(root->left, psize);
  9. BinaryTreeSize(root->right, psize);
  10. }

方法三:

用递归的思想分治,计算二叉树的结点数量,可以认为 数量 = 1 + 左子树数量 + 右子树数量,其中1是当前根结点数量

  1. //3、分治,不再遍历
  2. int BinaryTreeSize(BTNode* root)
  3. {
  4. return root == NULL ? 0 : 1
  5. + BinaryTreeSize(root->left)
  6. + BinaryTreeSize(root->right);
  7. }

求二叉树叶子结点个数

按照递归思想,计算二叉树的叶子结点数量,我们可以认为数量等于 = 0 + 左子树叶子结点数量 + 右子树叶子结点数量,0是因为当前根结点有子树,说明根结点不是叶子结点.

  1. //求叶子节点个数
  2. int BinaryTreeLeafSize(BTNode* root)
  3. {
  4. if (root == NULL)
  5. {
  6. return 0;
  7. }
  8. else if (root->left == NULL && root->right == NULL)
  9. {
  10. return 1;
  11. }
  12. else
  13. {
  14. return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
  15. }
  16. }

求二叉树第K层结点个数

核心思路:求当前树的第k层=左子树的第k-1层+右子树的第k-1层

  1. //求第k层节点个数
  2. //核心思路:求当前树的第k层=左子树的第k-1层+右子树的第k-1层
  3. int BinaryTreeLevelKSize(BTNode* root, int K)
  4. {
  5. if (root == NULL)
  6. {
  7. return 0;
  8. }
  9. if (K == 1)
  10. {
  11. return 1;
  12. }
  13. return BinaryTreeLevelKSize(root->left, K- 1) + BinaryTreeLevelKSize(root->right, K - 1);
  14. }

求二叉树的深度/高度

二叉树的高度等于1 + 左右子树高度的最大值.

  1. //二叉树的深度/高度
  2. int BinaryTreeDepth(BTNode* root)
  3. {
  4. if (root == NULL)
  5. {
  6. return 0;
  7. }
  8. int leftDepth = BinaryTreeDepth(root->left);
  9. int rightDepth = BinaryTreeDepth(root->right);
  10. return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
  11. }

查找二叉树中值为x的结点

递归分治,先判断当前结点是否是目标,然后查找左子树,再查找右子树.

如果左右子树都没有找到,就返回NULL

  1. BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
  2. {
  3. if (root == NULL)
  4. return NULL;
  5. if (root->data == x)
  6. return root;
  7. BTNode* retLeft = BinaryTreeFind(root->left, x);
  8. if (retLeft)
  9. {
  10. return retLeft;
  11. }
  12. BTNode* retRight = BinaryTreeFind(root->right, x);
  13. if (retRight)
  14. {
  15. return retRight;
  16. }
  17. return NULL;
  18. }

二叉树源代码

二叉树源代码

相关文章