二叉树的先序、中序、后序、层次遍历的递归以及非递归代码-----Java

本次拟整理一下二叉树的中序、后序、先序、层次遍历的递归以及非递归代码实现,
1.基础知识:
根据访问结点操作发生位置命名:
① NLR:前序遍历(Preorder Traversal 亦称(先序遍历))
——访问根结点的操作发生在遍历其左右子树之前。
② LNR:中序遍历(Inorder Traversal)
——访问根结点的操作发生在遍历其左右子树之中(间)。
③ LRN:后序遍历(Postorder Traversal)
——访问根结点的操作发生在遍历其左右子树之后。
注意:
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

2.先(根)序遍历的递归算法定义
若二叉树非空,则依次执行如下操作:
⑴ 访问根结点;
⑵ 遍历左子树;
⑶ 遍历右子树。
3.中(根)序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵访问根结点;
⑶遍历右子树。
4.后(根)序遍历得递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵遍历右子树;
⑶访问根结点。
5.递归实现代码

public static class TreeNode{//Definition for a binary tree node.
		int val;
		TreeNode left;
		TreeNode right;
	     public TreeNode(int x) //有参构造
	     { val = x; }
		}
	
①先序递归遍历
public static void Pre_visit(TreeNode root){
		if(root!=null){
			System.out.print(root.val);
			Pre_visit(root.left);
			Pre_visit(root.right);
		}
		
	}
	②中序递归遍历
	public static void in_visit(TreeNode root){
		if(root!=null){
			Pre_visit(root.left);
			System.out.print(root.val);
			Pre_visit(root.right);
		}	
	}
	③后序递归遍历
	public static void post_visit(TreeNode root){
		if(root!=null){
			Pre_visit(root.left);
			Pre_visit(root.right);
			System.out.print(root.val);
		}
	}
	非递归遍历:
	先序,中序,后序借助于栈
	层序遍历借助于队列先进先出的性质
	

//先序非递归
public static void pre_visit_no(TreeNode root){
	if(root!=null){
		Stack S = new Stack();
		S.push(root);
		while(!S.isEmpty()){
			root = (TreeNode) S.pop();
			System.out.print(root.val);
			while(root !=null){
				if(root.left !=null){
					System.out.print(root.left.val);
				}
					
				if(root.right != null){
					S.push(root.right);
				}
				root = root.left;
				}
			}
		}
		
	}

//中序非递归
public static void in_visit_no(TreeNode root){
	if(root!=null){
		Stack S = new Stack();
		S.push(root);
		while(!S.isEmpty()){
			while(S.peek() !=null){
				//将栈顶节点的做孩子节点相继入栈
				S.push( ((TreeNode) S.peek()).left );
			}
			S.pop();//空节点退栈
			if(!S.isEmpty()){
				root = S.pop();//移除栈顶元素,并返回其值
				System.out.println(root.val);//访问节点
				S.push(root.right);//节点的右孩子入栈
			}
			}
		}
}
//后序非递归
public static void post_visit_no(TreeNode root){
	if(root != null){
		Stack S = new Stack();
		S.push(root);//根节点进栈
		Boolean flag = false;//访问标记
		TreeNode p = null;//p指向刚被访问的结点
		while(!S.isEmpty()){
			while(S.peek() != null){
				S.push(S.peek().left);//将栈顶结点的做孩子相继入栈	
			}
			S.pop();//空节点退栈
			while(!S.isEmpty()){
				root =S.peek();
				if(root.left == null || root.right == p){
					System.out.println(root.val);//访问节点
					S.pop();//移除栈顶元素
					p = root;//p指向刚被访问的结点
					flag = true;//设置访问标记
					
				}else {
					S.push(root.right);//右孩子结点入栈
					flag = false;//设置未被访问标记
				}
				if(!flag){
					break;
				}
						
			}
		}
		
	}
}
	//层序遍历
public static void levelTraverse(TreeNode root){
	if(root != null){
		Queue L = new Queue();
		//构造队列
		L.offer(root);//根节点入队列
		while(!L.isEmpty()){
			root = (TreeNode) L.poll();
			System.out.println(root.val);//访问节点
			if(root.left != null){
				L.offer(root.left);//左孩子非空入队列
			}
			if(root.right != null){
				L.offer(root.right);//右孩子非空,入队列
			}
			
		}
		
	}
}

如有错误,请留言指出。

你可能感兴趣的:(数据结构,数据结构,二叉树遍历)