您的位置:首页 > 其它

二叉树基础题(一)

2017-03-16 15:23 211 查看
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/62423610冷血之心的博客)

二叉树基础题(二)

二叉树是在面试中经常被问到的,这里总结下二叉树的三种遍历方式,包括其遍历解法和迭代解法。
前序遍历也叫做先根遍历、先序遍历,可记做根左右。
        前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。中序遍历也叫做中,可记做左根右。       中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。
后序遍历是二叉树遍历的一种。左右根。       后序遍历指在访问根结点、遍历左子树与遍历右子树三者中,首先遍历左子树,然后遍历右子树,最后遍历访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。

1、前序遍历:

/**
* 前序遍历,中序遍历,后序遍历
* 前序遍历递归解法:
* (1)如果二叉树为空,空操作
* (2)如果二叉树不为空,访问根节点,前序遍历左子树,前序遍历右子树
*/
public static void preorderTraversalRec(TreeNode root){
if(root==null)
return ;
System.out.print(root.val+" ");
preorderTraversalRec(root.left);
preorderTraversalRec(root.right);
}
/**
* 前序遍历迭代解法:用一个辅助stack,总是把右孩子放进栈
*/
public static void preorderTraversal(TreeNode root){
if(root==null)
return ;
Stack<TreeNode> stack = new Stack<TreeNode>(); // 辅助stack
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur = stack.pop(); // 出栈栈顶元素
System.out.print(cur.val+" ");
// 关键点:要先压入右孩子,再压入左孩子,这样在出栈时会先打印左孩子再打印右孩子
if(cur.right!=null)
stack.push(cur.right);
if(cur.left!=null)
stack.push(cur.left);

}
}


2、中序遍历:

/**
* 中序遍历递归解法
* (1)如果二叉树为空,空操作。
* (2)如果二叉树不为空,中序遍历左子树,访问根节点,中序遍历右子树
*/
public static void inorderTraversalRec(TreeNode root){
if(root==null)
return;
inorderTraversalRec(root.left);
System.out.print(root.val+" ");
inorderTraversalRec(root.right);

}
/**
* 中序遍历迭代解法 ,用栈先把根节点的所有左孩子都添加到栈内,
* 然后输出栈顶元素,再处理栈顶元素的右子树
*/
public static void inorderTraversal(TreeNode root){
if(root==null)
return;
Stack<TreeNode> stack =new Stack<TreeNode>();
TreeNode cur = root;
while(true){
while(cur!=null){ // 先添加一个非空节点所有的左孩子到栈
stack.push(cur);
cur = cur.left;
}
if(stack.isEmpty())
break;

cur = stack.pop(); // 因为此时已经没有左孩子了,所以输出栈顶元素
System.out.print(cur.val+" ");
cur = cur.right; // 准备处理右子树
}
}

3、后序遍历:

/**
* 后序遍历递归解法
* (1)如果二叉树为空,空操作
* (2)如果二叉树不为空,后序遍历左子树,后序遍历右子树,访问根节点
*/
public static void postorderTraversalRec(TreeNode root) {
if (root == null)
return;
postorderTraversalRec(root.left);
postorderTraversalRec(root.right);
System.out.print(root.val + " ");
}
/**
* 后序遍历迭代解法
*/
public static void postorderTraversal(TreeNode root){
if (root == null)
return;
Stack<TreeNode> stack =new Stack<TreeNode>(); // 第一个stack用于添加node和它的左右孩子
Stack<TreeNode> output =new Stack<TreeNode>(); // 第二个stack用于翻转第一个stack输出

TreeNode cur = root;
stack.push(cur);
while(!stack.isEmpty()){ // 确保所有元素都被翻转转移到第二个stack
cur = stack.pop(); // 把栈顶元素添加到第二个stack
output.push(cur);

if(cur.left!=null) // 把栈顶元素的左孩子和右孩子分别添加入第一个stack
stack.push(cur.left);
if(cur.right!=null)
stack.push(cur.right);
}

while(!output.isEmpty()){ // 遍历输出第二个stack,即为后序遍历
cur = output.pop();
System.out.print(cur.val+" ");
}
}


测试类:
package com.ywq.package1;

public class Main {

/*
1
/ \
2 3
/ \ / \
4 5 7 6
*/
public static void main(String[] args){

TreeNode root = new TreeNode(1);
TreeNode r2 = new TreeNode(2);
TreeNode r3 = new TreeNode(3);
TreeNode r4 = new TreeNode(4);
TreeNode r5 = new TreeNode(5);
TreeNode r6 = new TreeNode(6);
TreeNode r7 = new TreeNode(7);

root.left = r2;
root.right = r3;
r2.left = r4;
r2.right = r5;
r3.right = r6;
r3.left = r7;

preorderTraversalRec(root);
System.out.println();
preorderTraversal(root);

inorderTraversalRec(root);
System.out.println();
inorderTraversal(root);

postorderTraversalRec(root);
System.out.println();
postorderTraversal(root);

}

}
// 建立二叉树节点类
class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val){
this.val = val;
}

}



如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,可以进群366533258一起交流学习哦~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: