您的位置:首页 > 其它

二叉树的前序,中序,后序遍历(递归非递归实现)

2017-07-11 22:54 274 查看
给定如图二叉树,请用递归和非递归的方式实现前序,中序,后序遍历



1.前序遍历

1.1 递归方式

递归方式十分简单,因为是前序遍历,所以在递归调用前先打印当前节点的值,然后分别将左孩子和右孩子作为参数传入递归函数

public void preTraversal1(TreeNode root){
if(root == null) return; //判空
System.out.println("print:"+root.val);
preTraversal1(root.left);
preTraversal1(root.right);
}
注:TreeNode的代码文末给出
1.2 非递归实现(使用一个栈)

一、我们定义一个栈stack,然后将root节点存入栈中(push操作)

二、只要当前栈中元素不为空,那么栈顶元素出栈(pop操作)并打印,如果出栈元素存在右孩子或左孩子(注意顺序),则将右孩子或左孩子加入栈中(push操作)

三、重复上述第二步操作

下面我们看图说话,



简单说下过程,

首先,push root元素到栈中,然后弹出root,并按顺序加入右孩子(3),左孩子(2)

然后,弹出栈顶元素(2),检查是否存在右孩子(5),左孩子(4),如果存在,则按顺序push进栈中

再次之,弹出栈顶元素(4),检查无孩子,继续弹出栈顶元素(5),检查无孩子,继续弹出栈顶元素(3),加入右孩子(7),加入左孩子(6)

最后,依次弹出无孩子的栈顶元素(6,7)

下面看代码实现

public void preTraversal2(TreeNode root){
if(root==null) return;
Deque<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(root);
while(stack.size()!=0){
TreeNode temp = stack.pop();
System.out.println("print:"+temp.val);
if(temp.right!=null) stack.push(temp.right);
if(temp.left!=null) stack.push(temp.left);
}
}
注:Deque为双端队列,这里用作栈

2.中序遍历

2.1 递归方式

有了之前的理解,这里直接贴出代码

public void inTraversal(TreeNode root){
if(root == null) return;
inTraversal(root.left);
System.out.println("print:"+root.val);
inTraversal(root.right);
} 2.2 非递归方式(一个栈实现)
一、我们定义一个栈stack,并将根节点root push进栈,定义一个current变量,开始时指向root节点

二、先把current节点压入栈中,然后将整棵树的左边界压入栈中(相对current节点而言),即不断令current=current.left,重复此步骤

三、重复第二步,当遇到current左节点为空时,弹出栈顶元素记为node,并令current=node.right,然后继续步骤二

四、直到stack为空时,结束整个过程

下面看图说话:



简单分析

首先,从root插入左边界得栈【1,2,4】,栈顶元素(4)已经无左边界,current变为null,出栈,而且无右孩子,current继续为null

然后,因为current继续为null,所以栈顶元素(2)弹出,右孩子(5)加入栈顶,但右孩子(5),左右边界均无,弹出,current继续为null

再次之,因为current继续为null,所以栈顶元素(1)弹出,右孩子(3)加入栈顶,左孩子(6)加入栈顶,而左孩子(6)无左右边界,弹出,current继续为null

最后,因为current继续为null,所以栈顶元素(3)弹出,右孩子(7)加入栈顶,而右孩子(7)无左右边界,继续弹出,此时栈为空,终止。

下面贴出代码:

public void inTraversal1(TreeNode root){
if(root==null) return;
Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode current = root;
stack.push(root);
while(stack.size()!=0){
if(current==null){
TreeNode temp = stack.pop();
System.out.println("print:"+temp.val);
if(temp.right!=null){
current = temp.right;
stack.push(current);
}
}else{
current = current.left;
if(current!=null) stack.push(current);
}
}
}


3. 后序遍历
3.1 递归方式

直接给出代码

public void postTraversal(TreeNode root){
if(root == null) return;
postTraversal(root.left);
postTraversal(root.right);
System.out.println("print:"+root.val);
}
3.2 非递归方式(两个栈)
一.声明一个栈stack1,并将根节点压入栈中

二.从stack1中弹出的节点记为current,并将current的左孩子和右孩子压入stack1

三.在整个过程中,从stack1弹出的元素均放入stack2中

四.不断重复二,三步骤,直到stack1为空为止

下面看图说话:



下面贴出代码

public void postTraversal1(TreeNode root){
Deque<TreeNode> stack1 = new LinkedList<TreeNode>();
Deque<TreeNode> stack2 = new LinkedList<TreeNode>();
stack1.push(root);
while(stack1.size()!=0){
TreeNode current = stack1.pop();
if(current.left!=null) stack1.push(current.left);
if(current.right!=null) stack1.push(current.right);
stack2.push(current);
}
while(stack2.size()!=0){
System.out.println("print:"+stack2.pop().val);
}
}

注:在分析前两个的基础上,自行分析第三个,后序遍历还有一种只用一个栈实现的方式,有兴趣可以自己查阅。
4.TreeNode代码

public int val = 0;
public TreeNode left = null;
public TreeNode right = null;
public TreeNode(int val){
this.val = val;
}

/**
* 构建一棵测试树
* */
public static TreeNode getTestTree(){
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(7);
return root;
}
}

支持原创,转载请标明出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 遍历
相关文章推荐