- 深度优先遍历
- 前序遍历(递归法,迭代法)
- 中序遍历(递归法,迭代法)
- 后序遍历(递归法,迭代法)
- 广度优先遍历
- 层次遍历(迭代法)
深度优先遍历:
递归法:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
preorder(list,root);
return list;
}
public List<Integer> preorder(List<Integer> list,TreeNode root){
if(root==null)
{return list;}
list.add(root.val);
preorder(list,root.left);
preorder(list,root.right);
return list;
}
}
这部分只需要在method中调整添加节点的顺序即可,其中前序是根左右,后序是左右根,中序是左根右。
迭代法:
利用栈
(前序)
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(stack.size()!=0){
TreeNode node = stack.pop();
if(node!=null){result.add(node.val);}
else{continue;}
//因为使用的是栈,只有先存右再存左弹出之后才是先左后右
if(node.right!=null){stack.push(node.right);}
if(node.left!=null){stack.push(node.left);}
}
return result;
}
}
(后序)
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
if(root==null) return list;
Stack<TreeNode> stack =new Stack<>();
stack.push(root);
while(stack.size()!=0){
//之前先add中间的在右再左
//取出后的顺序为中左右
//现将右和左的顺序对调
//取出后的顺序为中右左
//将整个数组反转得到左右中即后续遍历
TreeNode node = stack.pop();
if(node!=null){list.add(node.val);}
else{continue;}
//因为使用的是栈,只有先存右再存左弹出之后才是先左后右
if(node.left!=null){stack.push(node.left);}
if(node.right!=null){stack.push(node.right);}
}
Collections.reverse(list);
return list;
}
}
(中序)
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while(cur!=null||stack.size()!=0){
if(cur!=null){
stack.push(cur);
cur = cur.left;
}else{
cur = stack.pop();
result.add(cur.val);
cur = cur.right;
}
}
return result;
}
}
先将左全部遍历,到1后,1左为空,弹出1,result中添加1的数值,cur指向1右,1右为空,弹出4,result中添加4的数值,cur指向4右
统一迭代法(中序) :
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
if (root != NULL) st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
if (node != NULL) {
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
if (node->right) st.push(node->right); // 添加右节点(空节点不入栈)
st.push(node); // 添加中节点
st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (node->left) st.push(node->left); // 添加左节点(空节点不入栈)
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.top(); // 重新取出栈中元素
st.pop();
result.push_back(node->val); // 加入到结果集
}
}
return result;
}
};
这部分一定要结合网站上的动画1进行理解。