JAVA 实现二叉树,二叉树的递归遍历(前 中 后),二叉树的非递归遍历(先序 中序 后序),测树的深度和大小的方法

    xiaoxiao2025-02-17  17

    最近在复习数据结构 二叉树。 现在用的是Java 语言, 代码实现了测量深度和大小的 方法。 最主要的 是二叉树的 遍历 。 用了非递归和 递归的方法 来实现二叉树的先序、中序、后序遍历。 代码和注释如下:

    import java.util.Stack; /* * 此类 构造了二叉树 以及二叉树的递归遍历与非递归遍历 */ public class BinaryTree { //根节点 private TreeNode root = null; /* * Bingtree的构造函数 */ public BinaryTree() { root = new TreeNode(1, "A"); } /* * 下面构造节点和关系 * A * B C * D E F */ public void createBinaryTree() { //构造节点 TreeNode nodeB = new TreeNode(2, "B"); TreeNode nodeC = new TreeNode(3, "C"); TreeNode nodeD = new TreeNode(4, "D"); TreeNode nodeE = new TreeNode(5, "E"); TreeNode nodeF = new TreeNode(6, "F"); //构造关系 root.leftChild = nodeB; root.rightChild = nodeC; nodeB.leftChild = nodeD; nodeB.rightChild = nodeE; nodeC.rightChild = nodeF; } /* * 迭代法 求出树的高度 */ public int getHeight() { return getHeight(root); } public int getHeight(TreeNode node) { //节点为空 那么高度就为0; if(node == null) return 0; else { // i 和j的作用就是记录数有多高,不断迭代一个节点的左子树和右子数,直到子数出现空的情况 int i = getHeight(node.leftChild); int j = getHeight(node.rightChild); //i 和 j的比较是为了求出高度的最大值 return (i<j)?j+1:i+1 ; } } /* * 迭代法求树的大小 */ public int getSize() { return getSize(root); } public int getSize(TreeNode node) { //空节点大小为0 if(node == null) return 0; else { return 1+getSize(node.leftChild)+getSize(node.rightChild); } } /* * 迭代法实现 先顺遍历 */ public void preOrder(TreeNode node) { if(node == null) return; else { System.out.println("preOrder data:"+node.data); preOrder(node.leftChild); preOrder(node.rightChild); } } /* * 迭代法实现 中序遍历 */ public void midOrder(TreeNode node) { if (node == null) return; else { midOrder(node.leftChild); System.out.println("midOrder data"+node.data); midOrder(node.rightChild); } } /* * 迭代法实现 后序遍历 */ public void lastOrder(TreeNode node) { if(node == null) return; else { lastOrder(node.leftChild); lastOrder(node.rightChild); System.out.println("lastOrder data"+node.data); } } /* * 非迭代法实现 先序遍历 * * 此方法主要使用栈这种数据结构 * 首先将 根节点压入一个栈中 , 再将根节点弹出栈 * 压入根节点的左右子节点(注意的时 右节点要在左节点下面,因为栈是从上面弹出的) * 接着类似的操作 弹出根节点 加入子节点(没有子节点不进行操作) * 弹出栈的顺序就是 先序遍历的顺序 * * */ public void nonRecOrder(TreeNode node) { //空节点直接返回 if(node == null) return; //创建一个栈 来存节点 Stack<TreeNode> stack = new Stack<TreeNode>(); //传入根节点 stack.push(node); //栈不为空接着操作 while(!stack.isEmpty()) { //弹出根节点 TreeNode n = stack.pop(); //打印弹出节点 System.out.println("nonPreOrder data:"+n.data); //压入根节点的子节点 if(n.rightChild != null) //必须要用if判断 因为若果一个节点没有左或者右子节点 就会报空指针异常 stack.push(n.rightChild); if(n.leftChild != null) stack.push(n.leftChild); } } /* * 非迭代法实现 中序遍历 * 思想: * 传入 A 节点 * A节点不为空 则将操作单位移到A的左孩子上 (B) * 看B为不为空 不为空就一直移动到左孩子身上 * * 最终某个节点的左孩子为空 * 那么弹出栈顶节点(就是这个节点) * 操作单位移动到这个节点的右孩子上 * * */ public void nonmidOrder(TreeNode node) { if(node == null) return; Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode temp = node; //栈为空 且 节点空的时候退出 while(!stack.isEmpty() || temp!=null){ //当一个节点的左孩子不为空 if(temp != null) { //不断向左孩子遍历的过程 stack.push(temp); temp = temp.leftChild; }else { //当一个节点的左孩子为空 //返回此节点根节点 TreeNode bT = stack.pop(); //打印此节点的根节点 System.out.println("nonmidOrder data:"+bT.data); //遍历此节点根节点的后孩子 temp = bT.rightChild; } } } /* * 非迭代法实现 后序遍历 * 要用到两个栈,根节点首先入栈1,然后栈1依次出栈, * 每次出栈时该元素入栈2并将左右孩子压入栈1。最后得到的栈2依次出栈就是后序遍历结果 * */ public void nonlastOrder(TreeNode node) { if(node == null) return ; //需要使用两个栈 Stack<TreeNode> stack1 = new Stack<TreeNode>(); Stack<TreeNode> stack2 = new Stack<TreeNode>(); // stack1.push(node); while(!stack1.isEmpty()) { TreeNode tr = stack1.pop(); stack2.push(tr); if(tr.leftChild != null) stack1.push(tr.leftChild); if(tr.rightChild != null) stack1.push(tr.rightChild); } while(!stack2.isEmpty()) { System.out.println("nonlastOrder data:"+stack2.pop().data); } } /* * 构造节点类 */ public class TreeNode{ private int index ; //节点的下标 private String data; //节点的数据 private TreeNode leftChild; //节点的左子数 private TreeNode rightChild; //节点的右子数 public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public String getData() { return data; } public void setData(String data) { this.data = data; } //节点的构造函数 public TreeNode(int index,String data) { this.index = index; this.data = data; this.leftChild = null; this.rightChild = null; } } public static void main(String []args) { BinaryTree binaryTree = new BinaryTree(); binaryTree.createBinaryTree(); System.out.println("树的高度为:"+binaryTree.getHeight()); System.out.println("树的大小为:"+binaryTree.getSize()); // 迭代 前 中 后 遍历 binaryTree.preOrder(binaryTree.root); binaryTree.midOrder(binaryTree.root); binaryTree.lastOrder(binaryTree.root); //非迭代 实现 前 中 后 遍历 binaryTree.nonRecOrder(binaryTree.root); binaryTree.nonmidOrder(binaryTree.root); binaryTree.nonlastOrder(binaryTree.root); } }

    结果如图所示: 有的方法我解释的不是很容易懂,想要理解的透彻些可以举例子带入,自己用笔算一算更容易理解一些

    最新回复(0)