以下为Leecode的题以及参考大神做法
递归模板
public void traverse(TreeNode root,List<Integer> last){
if(root==null)//如果为null代表最后的子节点,结束循环
return;
last.add(root.val);//代表根节点,将根节点作为标志,这条语句的位置决定是前序,中序还是后序,在left,right的前面就是前序,在left,right的中面就是中序,在left,right的后面就是后序
traverse(root.left,last);//左子树继续递归
traverse(root.right,last);//左子树继续递归
}
迭代模板(前,中序)
将所有的左节点全部压入栈中,然后右节点,重复:把右节点的所有的左节点继续压入栈中,不断套娃
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
if(root==null)
return new ArrayList<>();
List<Integer> last= new ArrayList<>();
Stack<TreeNode> stack =new Stack<>();
while(true){//不断进行循环,重复
while(root!=null){
stack.push(root);
last.add(root.val);//此条语句决定前,中序遍历,在left前面为前序
root=root.left;//不断将左节点压入栈中
}
if(stack.isEmpty())//当栈为空代表根节点(第一个入栈的,最后出的)都遍历了,已经全部遍历完了
break;
TreeNode node = stack.pop();//出栈,向上一节点继续遍历
root=node.right;
}
return last;
}
}
以下的TreeNode都以此为结构
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
一:前序遍历
前序遍历:根–>左–>右
递归实现
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> last = new ArrayList<>();
traverse(root,last);
return last;
}
public void traverse(TreeNode root,List<Integer> last){
if(root==null)//如果为null代表最后的子节点都遍历了,结束循环
return;
last.add(root.val);//将根节点的数据添加到列表
traverse(root.left,last);//左子树继续递归
traverse(root.right,last);//左子树继续递归
}
}
迭代遍历
利用栈的我们先将所有的左节点压入栈,在压入完一个分支的所有左节点前先遍历当前根节点,然后出栈,然后遍历右节点
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
if(root==null)
return new ArrayList<>();
List<Integer> last= new ArrayList<>();
Stack<TreeNode> stack =new Stack<>();
while(true){
while(root!=null){//将左子树的所有左节点压入栈
stack.push(root);
last.add(root.val);
root=root.left;
}
if(stack.isEmpty())//如果为空,则表明已经到了根节点都已经遍历过了,该结束了
break;
TreeNode node = stack.pop();//出栈后下面进行右子树的遍历
root=node.right;
}
return last;
}
}
二:中序遍历
左->根->右
递归实现
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> last= new ArrayList<>();
traverse(root,last);
return last;
}
public void traverse(TreeNode root,List<Integer> last){
if(root==null)//如果为null代表最后的子节点,结束循环
return;
traverse(root.left,last);//左子树继续递归
last.add(root.val);//将根节点的数据添加到列表
traverse(root.right,last);//右子树继续递归
}
}
迭代实现
利用栈的我们先将所有的左节点压入栈,在压入完一个分支的所有左节点后,然后出栈,遍历当前根节点,然后遍历右节点
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
if(root==null)
return new ArrayList<>();
List<Integer> last= new ArrayList<>();
Stack<TreeNode> stack =new Stack<>();
while(true){
while(root!=null){
stack.push(root);
root=root.left;
}
if(stack.isEmpty())
break;
TreeNode node = stack.pop();
last.add(node.val);//遍历根节点
root=node.right;
}
return last;
}
}
三:后序遍历
左->右->根,后序比较难一些,需要判断是否已经将右子树遍历,需要记录前一个节点的信息~,如果没有需要进行遍历才能进行根节点的处理
递归实现
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> last= new ArrayList<>();
traverse(root,last);
return last;
}
public void traverse(TreeNode root,List<Integer> last){
if(root==null)//如果为null代表最后的子节点,结束循环
return;
traverse(root.left,last);//左子树继续递归
traverse(root.right,last);//右子树继续递归
last.add(root.val);//将根节点的数据添加到列表
}
}
迭代遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
if(root==null)
return new ArrayList<>();
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack =new Stack<>();
TreeNode pre=null;//作为当前前面一个节点,用来后面判断右子树是否遍历完
while(root!=null){//将所有的左子树压入栈中
pre =root;
stack.push(root);
root=root.left;
}
while(!stack.isEmpty()){
TreeNode node = stack.peek();//取当前栈顶
if(pre==node.right||node.right==null){//当在一棵树的最最最下层子节点时node.right为null,当不是最下层子节点时,pre等于上层节点的右子树,这两种情况时说明该节点的右子树已经遍历完~则左->右->根,该进行根的操作
pre=stack.pop();
last.add(node.val);
}else{
root=node.right;//如果没有遍历完右子树,则进行右子树遍历,如果该右子树还有孩子左子树,进行右子树的将所有的左子树压入栈
while(root!=null){//
pre=root;
stack.push(root);
root=root.left;
}
}
}
return last;
}
}
三:层次遍历
递归实现
该算法从一个根节点开始,首先访问节点本身。 然后遍历它的相邻节点,其次遍历它的二级邻节点、三级邻节点,以此类推。
当我们在树中进行广度优先搜索时,我们访问的节点的顺序是按照层序遍历顺序的。
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> last=new ArrayList<>();//用于存储每一层的数据,而每一层的数据就放在一个ArrayList里面,再把所有的放到一个list里面
traverse(root,last,0);
return last;
}
public void traverse(TreeNode root,List<List<Integer>> last,int level){//level用来表示当前的层数
if(root==null)
return;
if(level==last.size())//当当前层数为list的大小时,增加一条为下文做准备
last.add(new ArrayList<>());
last.get(level).add(root.val);//通过level索引进行操作
traverse(root.left,last,level+1);
traverse(root.right,last,level+1);
}
}
迭代实现
按照BFS的思想将一个节点出队时将它所有的子节点入队
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
if(root==null)
return new ArrayList<>();
List<List<Integer>> last=new ArrayList<>();
Queue<TreeNode> queue =new LinkedList<>();//用来存储节点
queue.add(root);
while(!queue.isEmpty()){
int n=queue.size();//用来表示root下面一层有多少个节点
List<Integer> temp=new ArrayList<>();
for(int i=0;i<n;i++){//用来遍历下层节点
TreeNode node =queue.remove();
temp.add(node.val);
if(node.left!=null){//不为空则入列
queue.add(node.left);
}
if(node.right!=null){
queue.add(node.right);
}
}
last.add(temp);
}
return last;
}
}