二叉树的遍历方式
假定二叉树的节点的定义如下:
1 | struct TreeNode{ |
对节点的数据的访问通过调用visit()实现,例如当要把节点的数据按照遍历顺序加入一个向量nums中,可以将visit(x)改为nums.push_back(x)。
1 二叉树的广度优先遍历(层次遍历)
广度优先遍历可以用队列来实现
1 | void levelTraversal(TreeNode* root) |
2 二叉树的深度优先遍历
2.1 递归算法
1 | //前序遍历 |
2.2 非递归算法
2.2.1 非递归算法实现1
参考来源:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/yan-se-biao-ji-fa-yi-chong-tong-yong-qie-jian-ming/
(遍历过程可以认为每个节点都将被访问两次。当访问到一个节点时,如果是第一次访问,将这个节点、这个节点的非空左右节点加入栈(入栈的顺序根据访问顺序调整),如果是第二次访问,说明是回溯到了这个节点,此时调用visit()函数访问这个节点的数据)
1 | //前序遍历 |
2.2.2 非递归算法实现2
前序遍历
1 | void preTrav(TreeNode* root) |
另外一种写法:
对于任意一个结点node,具体步骤如下:
a)访问之,并把结点node入栈,当前结点置为左孩子;
b)判断结点node是否为空,若为空,则取出栈顶结点并出栈,将右孩子置为当前结点;否则重复a)步直到当前结点为空或者栈为空(可以发现栈中的结点就是为了访问右孩子才存储的)
1 | public void preOrderTraverse2(TreeNode root) { |
中序遍历
1 | void inTrav(TreeNode* root) |
另外一种写法:
1 | public void inOrderTraverse2(TreeNode root) { |
后序遍历
1 | void postTrav(TreeNode* root) |
另外一种方式:
1 | class Solution { |
2.2.3 非递归实现算法3
这也是一种统一的非递归迭代算法,这种方法和2.2.1相同,只不过换了一种实现方式
1 | vector<int> preorderTraversal(TreeNode* root) { |