二叉樹的遍歷(Java)
阿新 • • 發佈:2019-01-31
樹可以以不同的方式遍歷。以下是遍歷樹的常用方法。
深度優先遍歷:
(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();
}
}
上面二叉樹廣度遍歷中一次列印每一行的節點,這樣方便分別對每一行節點單獨處理,廣度遍歷中一般都會要求單獨處理每一行。