当前位置:   article > 正文

数据结构初阶:二叉树(二)

数据结构初阶:二叉树(二)

二叉树链式结构的实现

前置说明

在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在对二叉树结构掌握还不够深入,为了降低学习成本,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等二叉树结构了解的差不多时,我们反过头再来研究二叉树真正的创建方式。
  1. typedef int BTDataType;
  2. typedef struct BinaryTreeNode
  3. {
  4. BTDataType data;
  5. struct BinaryTreeNode* left;
  6. struct BinaryTreeNode* right;
  7. }TreeNode;
  8. TreeNode* BuyTreeNode(int x)
  9. {
  10. TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));
  11. assert(node);
  12. node->data = x;
  13. node->left = NULL;
  14. node->right = NULL;
  15. return node;
  16. }
  17. TreeNode* CreateTree()
  18. {
  19. TreeNode* node1 = BuyTreeNode(1);
  20. TreeNode* node2 = BuyTreeNode(2);
  21. TreeNode* node3 = BuyTreeNode(3);
  22. TreeNode* node4 = BuyTreeNode(4);
  23. TreeNode* node5 = BuyTreeNode(5);
  24. TreeNode* node6 = BuyTreeNode(6);
  25. TreeNode* node7 = BuyTreeNode(7);
  26. node1->left = node2;
  27. node1->right = node4;
  28. node2->left = node3;
  29. node4->left = node5;
  30. node4->right = node6;
  31. node5->right = node7;
  32. return node1;
  33. }
注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式后面详解重点讲解。
再看二叉树基本操作前,再回顾下二叉树的概念, 二叉树是:
1. 空树
2. 非空:根节点,根节点的左子树、根节点的右子树组成的。
从概念中可以看出,二叉树定义是递归式的,因此后面基本操作中基本都是按照该概念实现的。

二叉树的遍历

前序、中序以及后序遍历

学习二叉树结构,最简单的方式就是遍历。所谓 二叉树遍历 (Traversal) 是按照某种特定的规则,依次对二叉 树中的节点进行相应的操作,并且每个节点只操作一次 。访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,也是二叉树上进行其它运算的基础。
按照规则,二叉树的遍历有: 前序 / 中序 / 后序的递归结构遍历
1. 前序遍历 (Preorder Traversal 亦称先序遍历 )—— 访问根结点的操作发生在遍历其左右子树之前。 (根 左子树 右子树)
2. 中序遍历 (Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中(间)。
(左子树 根 右子树)
3. 后序遍历 (Postorder Traversal)—— 访问根结点的操作发生在遍历其左右子树之后。
(左子树 右子树 根)
由于被访问的结点必是某子树的根, 所以 N(Node )、 L(Left subtree )和 R(Right subtree )又可解释为 根、根的左子树和根的右子树 NLR LNR LRN 分别又称为先根遍历、中根遍历和后根遍历。
  1. // 二叉树前序遍历
  2. void PrevOrder(TreeNode* root)
  3. {
  4. if (root == NULL)
  5. {
  6. printf("N ");
  7. return;
  8. }
  9. printf("%d ", root->data);
  10. PrevOrder(root->left);
  11. PrevOrder(root->right);
  12. }
  13. // 二叉树中序遍历
  14. void InOrder(TreeNode* root)
  15. {
  16. if (root == NULL)
  17. {
  18. printf("N ");
  19. return;
  20. }
  21. InOrder(root->left);
  22. printf("%d ", root->data);
  23. InOrder(root->right);
  24. }
  25. // 二叉树后序遍历
  26. void PostOrder(TreeNode* root)
  27. {
  28. if (root == NULL)
  29. {
  30. printf("N ");
  31. return;
  32. }
  33. PostOrder(root->left);
  34. PostOrder(root->right);
  35. printf("%d ", root->data);
  36. }
下面分析前序递归遍历,中序与后序图解类似:
前序遍历结果: 1 2 3 4 5 6
中序遍历结果: 3 2 1 5 4 6
后序遍历结果: 3 2 5 6 4 1

节点个数以及高度等

二叉树节点个数:

思路:分治子问题:左子树节点个数+右子树节点个数+1
代码:
  1. // 二叉树节点个数
  2. int TreeSize(TreeNode* root)
  3. {
  4. return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
  5. }
二叉树叶子节点个数:
思路:
代码:
  1. // 叶子节点的个数
  2. int TreeLeafSize(TreeNode* root)
  3. {
  4. // 空 返回0
  5. if (root == NULL)
  6. return 0;
  7. // 不是空,是叶子 返回1
  8. if (root->left == NULL
  9. && root->right == NULL)
  10. return 1;
  11. // 不是空 也不是叶子 分治=左右子树叶子之和
  12. return TreeLeafSize(root->left) +
  13. TreeLeafSize(root->right);
  14. }

二叉树的高度:

思路;

代码:
  1. //int TreeHeight(TreeNode* root)
  2. //{
  3. // if (root == NULL)
  4. // return 0;
  5. // int leftHeight = TreeHeight(root->left);
  6. // int rightHeight = TreeHeight(root->right);
  7. //
  8. // return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
  9. //}
  10. int TreeHeight(TreeNode* root)
  11. {
  12. if (root == NULL)
  13. return 0;
  14. return fmax(TreeHeight(root->left), TreeHeight(root->right)) + 1;
  15. }

二叉树第k层节点个数

思路:

代码:

  1. int TreeLevelK(TreeNode* root, int k)
  2. {
  3. assert(k > 0);
  4. if (root == NULL)
  5. return 0;
  6. if (k == 1)
  7. return 1;
  8. return TreeLevelK(root->left, k-1)
  9. + TreeLevelK(root->right, k-1);
  10. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/426554
推荐阅读
相关标签
  

闽ICP备14008679号