二叉树的遍历算法(一)
程序员文章站
2022-10-03 17:30:51
///*// 复习一下 树的遍历算法// 递归方法:前中后// 非递归方法:前中后+层次//// 树的定义://public class TreeNode {// int val;// TreeNode left;// TreeNode right;// TreeNode(int x){// val =x;// }//}////*///public class Q1 {//递归函数写的时候就跟手算是一样的...
二叉树的遍历算法
复习一下 树的遍历算法
递归方法:前中后
非递归方法:前中后+层次
树的定义:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
val =x;
}
}
public class Q1 {
//递归函数写的时候就跟手算是一样的,只不过相应的读取变成一个存储或者输出的过程。
//前序递归
public static void RecurPreOrder(TreeNode root){
if(root !=null){
System.out.println(root.val);
RecurPreOrder(root.left);
RecurPreOrder(root.right);
}
}
//中序递归
public static void RecurInOrder(TreeNode root){
if(root != null){
RecurInOrder(root.left);
System.out.println(root.val);
RecurInOrder(root.right);
}
}
//后序递归
public static void RecurPostOrder(TreeNode root){
if(root != null){
RecurPostOrder(root.left);
RecurPostOrder(root.right);
System.out.println(root.val);
}
}
//先序遍历的非递归算法使用的是栈,迭代核心的是“栈顶是根节点,访问,遍历先右后左,”
//前序非递归
public static List<Integer> NonRecurPreOrder(TreeNode root){
List<Integer> list = new ArrayList<Integer>();
if (root == null) return list;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
while( !stack.empty()){
TreeNode p = stack.pop();
list.add(Integer.valueOf(p.val));
if(p.right != null){
stack.push(p.right);
}
if(p.left != null){
stack.push(p.left);
}
}
return list;
}
//中序遍历的非递归算法
//还是利用栈:迭代的思想是,栈顶是左节点,访问发生在该节点无左子树的时候
public static List<Integer> NonRecurInOrder(TreeNode root){
List<Integer> list = new ArrayList<Integer>();
if(root ==null) return list;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode tmp = root;
while (! stack.empty()|| tmp != null){
//1.遍历全部左子树
if(tmp!= null){
stack.push(tmp);
tmp = tmp.left;
}else{
//2.左子树遍历完成以后,栈顶元素依次出栈访问,如果栈顶元素存在右子树,右子树入栈迭代成为新的栈顶
tmp = stack.pop();
list.add(Integer.valueOf(tmp.val));
tmp = tmp.right;
//这三步实现了不用额外的判断即可完成对于右子树的回溯NB
}
}
return list;
}
//后序遍历的非递归算法:这个版本太奇淫技巧了,学不来学不来
//依旧是利用栈:参考中序遍历的左-根-右,后序遍历的是 左-右-根
public static List<Integer> NonRecurPostOrder(TreeNode root){
LinkedList<Integer> list = new LinkedList<>();
if(root ==null ) return list;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode tmp = root;
while ( ! stack.empty() || tmp != null){
//1. 遍历全部右子树,结果容器用队列表示,
if(tmp !=null){
list.addFirst(tmp.val);
stack.push(tmp);
tmp = tmp.right;
}else{
//2.右子树遍历完成以后,栈顶元素依次出栈,如果存在的左子树,返回1。
tmp = stack.pop();
tmp = tmp.left;
}
}
return list;
}
//参考另一个大佬的思路:
//所谓的非递归算法就是使用栈来模仿递归,由栈的顺序可以知道,先入后出,所以:
//前序遍历就是在访问访问左子树之前,对父节点进行访问。即左节点的出栈的时候
//中序遍历就是在访问左子树之后,右子树之前,对父节点进行操作。
//后序遍历就是在访问左右子树以后,对父节点进行操作。即左右子树都出栈以后
public static List<Integer> NonRecurPreOrder2(TreeNode root) {
if(root == null ) return Collections.emptyList();
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (! stack.empty()){
//弹出节点用以判断节点是否已经访问,非空表示没有访问
TreeNode t = stack.pop();
if(t != null){
if(t.right != null) stack.push(t.right);
if(t.left != null) stack.push(t.left);
stack.push(t);
stack.push(null);
}else{
res.add(Integer.valueOf(stack.pop().val));
}
}
return res;
}
public static void main(String[] args) {
String str = "[1,2,3,4,5,6]";
TreeNode root = wrapper.stringToTreeNode(str);
wrapper.prettyPrintTree(root);
System.out.println(NonRecurPreOrder2(root));
}
}
本文地址:https://blog.csdn.net/qq_33816775/article/details/107362140
上一篇: 荐 【JavaWeb】89:Request请求详解
下一篇: 澳门哪里拍照好看 澳门拍照好看景点大全