Java实现二叉树的深度优先遍历和广度优先遍历算法示例
本文实例讲述了java实现二叉树的深度优先遍历和广度优先遍历算法。分享给大家供大家参考,具体如下:
1. 分析
二叉树的深度优先遍历的非递归的通用做法是采用栈,广度优先遍历的非递归的通用做法是采用队列。
深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历、中序遍历、后序遍历。具体说明如下:
先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树。
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树。
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
广度优先遍历:又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(也可以从右往左)访问结点,访问完一层就进入下一层,直到没有结点可以访问为止。
2. 举例说明
对下图所示的二叉排序树进行遍历,要求使用先序遍历(递归、非递归)、中序遍历(递归、非递归)、后序遍历(递归、非递归)和广度优先遍历。
① 参考代码
package binarytreetraversetest; import java.util.linkedlist; import java.util.queue; /** * 二叉树的深度优先遍历和广度优先遍历 * @author fantasy * @version 1.0 2016/10/05 - 2016/10/07 */ public class binarytreetraversetest { public static void main(string[] args) { binarysorttree<integer> tree = new binarysorttree<integer>(); tree.insertnode(35); tree.insertnode(20); tree.insertnode(15); tree.insertnode(16); tree.insertnode(29); tree.insertnode(28); tree.insertnode(30); tree.insertnode(40); tree.insertnode(50); tree.insertnode(45); tree.insertnode(55); system.out.print("先序遍历(递归):"); tree.preordertraverse(tree.getroot()); system.out.println(); system.out.print("中序遍历(递归):"); tree.inordertraverse(tree.getroot()); system.out.println(); system.out.print("后序遍历(递归):"); tree.postordertraverse(tree.getroot()); system.out.println(); system.out.print("先序遍历(非递归):"); tree.preordertraversenorecursion(tree.getroot()); system.out.println(); system.out.print("中序遍历(非递归):"); tree.inordertraversenorecursion(tree.getroot()); system.out.println(); system.out.print("后序遍历(非递归):"); tree.postordertraversenorecursion(tree.getroot()); system.out.println(); system.out.print("广度优先遍历:"); tree.breadthfirsttraverse(tree.getroot()); } } /** * 结点 */ class node<e extends comparable<e>> { e value; node<e> left; node<e> right; node(e value) { this.value = value; left = null; right = null; } } /** * 使用一个先序序列构建一棵二叉排序树(又称二叉查找树) */ class binarysorttree<e extends comparable<e>> { private node<e> root; binarysorttree() { root = null; } public void insertnode(e value) { if (root == null) { root = new node<e>(value); return; } node<e> currentnode = root; while (true) { if (value.compareto(currentnode.value) > 0) { if (currentnode.right == null) { currentnode.right = new node<e>(value); break; } currentnode = currentnode.right; } else { if (currentnode.left == null) { currentnode.left = new node<e>(value); break; } currentnode = currentnode.left; } } } public node<e> getroot(){ return root; } /** * 先序遍历二叉树(递归) * @param node */ public void preordertraverse(node<e> node) { system.out.print(node.value + " "); if (node.left != null) preordertraverse(node.left); if (node.right != null) preordertraverse(node.right); } /** * 中序遍历二叉树(递归) * @param node */ public void inordertraverse(node<e> node) { if (node.left != null) inordertraverse(node.left); system.out.print(node.value + " "); if (node.right != null) inordertraverse(node.right); } /** * 后序遍历二叉树(递归) * @param node */ public void postordertraverse(node<e> node) { if (node.left != null) postordertraverse(node.left); if (node.right != null) postordertraverse(node.right); system.out.print(node.value + " "); } /** * 先序遍历二叉树(非递归) * @param root */ public void preordertraversenorecursion(node<e> root) { linkedlist<node<e>> stack = new linkedlist<node<e>>(); node<e> currentnode = null; stack.push(root); while (!stack.isempty()) { currentnode = stack.pop(); system.out.print(currentnode.value + " "); if (currentnode.right != null) stack.push(currentnode.right); if (currentnode.left != null) stack.push(currentnode.left); } } /** * 中序遍历二叉树(非递归) * @param root */ public void inordertraversenorecursion(node<e> root) { linkedlist<node<e>> stack = new linkedlist<node<e>>(); node<e> currentnode = root; while (currentnode != null || !stack.isempty()) { // 一直循环到二叉排序树最左端的叶子结点(currentnode是null) while (currentnode != null) { stack.push(currentnode); currentnode = currentnode.left; } currentnode = stack.pop(); system.out.print(currentnode.value + " "); currentnode = currentnode.right; } } /** * 后序遍历二叉树(非递归) * @param root */ public void postordertraversenorecursion(node<e> root) { linkedlist<node<e>> stack = new linkedlist<node<e>>(); node<e> currentnode = root; node<e> rightnode = null; while (currentnode != null || !stack.isempty()) { // 一直循环到二叉排序树最左端的叶子结点(currentnode是null) while (currentnode != null) { stack.push(currentnode); currentnode = currentnode.left; } currentnode = stack.pop(); // 当前结点没有右结点或上一个结点(已经输出的结点)是当前结点的右结点,则输出当前结点 while (currentnode.right == null || currentnode.right == rightnode) { system.out.print(currentnode.value + " "); rightnode = currentnode; if (stack.isempty()) { return; //root以输出,则遍历结束 } currentnode = stack.pop(); } stack.push(currentnode); //还有右结点没有遍历 currentnode = currentnode.right; } } /** * 广度优先遍历二叉树,又称层次遍历二叉树 * @param node */ public void breadthfirsttraverse(node<e> root) { queue<node<e>> queue = new linkedlist<node<e>>(); node<e> currentnode = null; queue.offer(root); while (!queue.isempty()) { currentnode = queue.poll(); system.out.print(currentnode.value + " "); if (currentnode.left != null) queue.offer(currentnode.left); if (currentnode.right != null) queue.offer(currentnode.right); } } }
② 输出结果
先序遍历(递归):35 20 15 16 29 28 30 40 50 45 55
中序遍历(递归):15 16 20 28 29 30 35 40 45 50 55
后序遍历(递归):16 15 28 30 29 20 45 55 50 40 35
先序遍历(非递归):35 20 15 16 29 28 30 40 50 45 55
中序遍历(非递归):15 16 20 28 29 30 35 40 45 50 55
后序遍历(非递归):16 15 28 30 29 20 45 55 50 40 35
广度优先遍历:35 20 40 15 29 50 16 28 30 45 55
更多关于java算法相关内容感兴趣的读者可查看本站专题:《java数据结构与算法教程》、《java操作dom节点技巧总结》、《java文件与目录操作技巧汇总》和《java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
推荐阅读