[关闭]
@HUST-SuWB 2018-04-22T03:29:06.000000Z 字数 2067 阅读 520

二叉树的遍历

扩展练习


二叉树的基本概念

在计算机科学中,二叉树是每个结点最多有两个子树的有序树。通常根的子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。二叉树的每个结点至多只有二棵子树(不存在出度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。(二叉树

二叉树的遍历

一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
⑴访问结点本身(N),
⑵遍历该结点的左子树(L),
⑶遍历该结点的右子树(R)。
以上三种操作有六种执行次序:
NLR、LNR、LRN、NRL、RNL、RLN。
注意:
前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。
遍历命名
根据访问结点操作发生位置命名:
① NLR:前序遍历(PreorderTraversal亦称(先序遍历))
——访问根结点的操作发生在遍历其左右子树之前。
② LNR:中序遍历(InorderTraversal)
——访问根结点的操作发生在遍历其左右子树之中(间)。
③ LRN:后序遍历(PostorderTraversal)
——访问根结点的操作发生在遍历其左右子树之后。
注意:
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。
二叉树遍历

遍历的具体实现

LeetCode上有三道相关的题,分别求解二叉树的前序遍历、中序遍历和后序遍历

1、前序遍历

C++的迭代实现

  1. /**
  2. * Definition for binary tree
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. vector<int> preorderTraversal(TreeNode *root) {
  13. vector<int> path;
  14. stack<TreeNode*> stk;//用栈保存一路遍历过来的根节点们,取完相应左子树的值后再pop出根节点去取右子树
  15. while(root != NULL || !stk.empty())
  16. {
  17. if(root != NULL)
  18. {
  19. while(root)
  20. {
  21. path.push_back(root->val);
  22. stk.push(root);
  23. root=root->left;
  24. }
  25. }
  26. else{
  27. root = stk.top()->right;
  28. stk.pop();
  29. }
  30. }
  31. return path;
  32. }
  33. };

2、中序遍历

Java的迭代实现

  1. /**
  2. * Definition for binary tree
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. public class Solution {
  11. public List<Integer> inorderTraversal(TreeNode root) {
  12. List<Integer> list = new ArrayList<Integer>();
  13. Stack<TreeNode> stack = new Stack<TreeNode>();
  14. while(root!=null || !stack.isEmpty()){
  15. while(root!=null){
  16. stack.push(root);
  17. root = root.left;
  18. }
  19. if(!stack.isEmpty()){
  20. TreeNode node = stack.pop();
  21. list.add(node.val);
  22. root = node.right;
  23. }
  24. }
  25. return list;
  26. }
  27. }

3、后序遍历

Java的递归实现

  1. /**
  2. * Definition for binary tree
  3. * public class TreeNode {
  4. * int val;
  5. * TreeNode left;
  6. * TreeNode right;
  7. * TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. public class Solution {
  11. private List<Integer> list = new ArrayList<Integer>();
  12. public List<Integer> postorderTraversal(TreeNode root) {
  13. if(root!=null){
  14. postorderTraversal(root.left);
  15. postorderTraversal(root.right);
  16. list.add(root.val);
  17. }
  18. return list;
  19. }
  20. }

总结

处理此类问题,递归的思路会更加简单而直接,但是会带来更大的系统开销。迭代在思维上比较难,但执行很快。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注