树可以以不同的方式遍历。以下是遍历树的常用方法。
深度优先遍历:
(a)中序遍历(左、根、右):4 2 5 1 3
(b)先序遍历(根、左、右):1 2 4 5 3
(c)后序遍历(左、右、根) :4 5 2 3 1
广度优先或水平顺序遍历:
1 2 3 4 5
先序遍历
算法Inorder(树)
1.遍历左子树,即调用Inorder(left-subtree)
2.访问根节点。
3.遍历右子树,即调用Inorder(右子树)
中序遍历
算法Preorder(树)
1.访问根节点。
2.遍历左子树,即调用Preorder(left-subtree)
3.遍历右子树,即调用Preorder(右子树)
后序遍历
算法Postorder(树)
1.遍历左子树,即调用Postorder(左子树)
2.遍历右子树,即调用Postorder(右子树)
3.访问根。
二叉树深度遍历的递归实现
代码
class Node
{
int key;
Node left, right;
public Node(int item)
{
key = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
BinaryTree()
{
root = null;
}
/*后序遍历*/
void printPostorder(Node node)
{
if (node == null)
return;
printPostorder(node.left);
printPostorder(node.right);
System.out.print(node.key + " ");
}
/* 中序遍历*/
void printInorder(Node node)
{
if (node == null)
return;
printInorder(node.left);
System.out.print(node.key + " ");
printInorder(node.right);
}
/* 前序遍历*/
void printPreorder(Node node)
{
if (node == null)
return;
System.out.print(node.key + " ");
printPreorder(node.left);
printPreorder(node.right);
}
void printPostorder() { printPostorder(root); }
void printInorder() { printInorder(root); }
void printPreorder() { printPreorder(root); }
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
System.out.println("\n二叉树的前序遍历是 ");
tree.printPreorder();
System.out.println("\n二叉树的遍历遍历 ");
tree.printInorder();
System.out.println("\n二叉树的后序遍历是 ");
tree.printPostorder();
}
}
输出:
二叉树的前序遍历是
1 2 4 5 3
二叉树的遍历遍历
4 2 5 1 3
二叉树的后序遍历是
4 5 2 3 1
二叉树深度遍历的非递归实现
树的结构
class TreeNode{
int val;
TreeNode left=null;
TreeNode right=null;
public TreeNode(int val) {
this.val = val;
}
}
①栈实现前序遍历
public static void PreTraverseWithStack(TreeNode pRoot)
{
Stack<TreeNode> stack=new Stack<TreeNode>();
if(pRoot!=null)
{
stack.push(pRoot);
}
while(!stack.isEmpty())
{
TreeNode curNode=stack.pop();
System.out.print(curNode.val+" ");
if(curNode.right!=null)
{
stack.push(curNode.right);
}
if(curNode.left!=null)
{
stack.push(curNode.left);
}
}
}
②栈实现中序遍历
public static void InTraverseWithStack(TreeNode pRoot)
{
if(pRoot!=null)
{
Stack<TreeNode> stack=new Stack<TreeNode>();
while(!stack.isEmpty()||pRoot!=null)
{
if(pRoot!=null)
{
stack.push(pRoot);
pRoot=pRoot.left;
}
else {
pRoot=stack.pop();
System.out.println(pRoot.val);
pRoot=pRoot.right;
}
}
}
}
③栈实现后序遍历
public void PosTraverseWithStack(TreeNode pRoot)
{
if(Head!=null)
{
Stack<TreeNode> stack1=new Stack<TreeNode>();
Stack<TreeNode> stack2=new Stack<TreeNode>();
stack1.push(pRoot);
while(!stack1.isEmpty())
{
TreeNode curNode=stack1.pop();
stack2.push(curNode);
if(curNode.left!=null)
{
stack1.push(curNode.left);
}
if(curNode.right!=null)
{
stack1.push(curNode.right);
}
}
while(!stack2.isEmpty())
{
System.out.println(stack2.pop().val);
}
}
}
二叉树的广度遍历
④队列实现二叉树广度遍历
public void TraverseWithQueue(TreeNode pRoot)
{
if(pRoot==null)
return ;
Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.add(pRoot);
while(!queue.isEmpty())
{
int len=queue.size();
for(int i=0;i<len;i++)
{
TreeNode cur=queue.poll();
System.out.print(cur.val+" ");
if(cur.left!=null)
queue.add(cur.left);
if (cur.right!=null) {
queue.add(cur.right);
}
}
System.out.println();
}
}
上面二叉树广度遍历中一次打印每一行的节点,这样方便分别对每一行节点单独处理,广度遍历中一般都会要求单独处理每一行。