日撸java_day21

第 21 天: 二叉树的深度遍历的递归实现
21.1 二叉树的遍历比存储、建立要简单. 所以先“手动”建立一个二叉树来玩.
21.2 递归算法写起来就是舒服. 前、中、后序的代码差别只有输出语句的位置.
21.3 不需要额外的节点类, 每棵二叉树 (树) 都可以从自己的根结点找到其它所有节点. 这个需要自悟.
21.4 获取二叉树的层次、总节点数, 也需要递归. 以后可能要用, 这里就一并写了.
 

package datastructures.tree;

/**
 * ClassName: BinaryCharTree
 * Package: datastructures.tree
 * Description: Binary tree with char type elements.
 *
 * @Author: luv_x_c
 * @Create: 2023/4/25 14:44
 */
public class BinaryCharTree {
    /**
     * 二叉树的根节点
     */
    private BinaryTreeNode root;

    private static class BinaryTreeNode {
        /**
         * The value in char.
         */
        private char value;
        /**
         * The left child.
         */
        private BinaryTreeNode left;
        /**
         * The right child.
         */
        private BinaryTreeNode right;

        /**
         * A constructor.
         *
         * @param paraValue The given value.
         */
        public BinaryTreeNode(char paraValue) {
            this.value = paraValue;
            this.left = null;
            this.right = null;
        }//
    }// Of class BinaryTreeNode

    /**
     * 构造函数
     */
    public BinaryCharTree() {
        root = null;
    }

    /**
     * ********************
     * Manually construct a tree. Only for testing.
     * ********************
     */
    public static BinaryCharTree manualConstructTree() {
        // Step 1. Construct a null tree.
        BinaryCharTree resultTree = new BinaryCharTree();

        // Step 2. Construct all nodes. The first node is the root.
        BinaryTreeNode tempNodeA = new BinaryTreeNode('a');
        BinaryTreeNode tempTreeB = new BinaryTreeNode('b');
        BinaryTreeNode tempTreeC = new BinaryTreeNode('c');
        BinaryTreeNode tempTreeD = new BinaryTreeNode('d');
        BinaryTreeNode tempTreeE = new BinaryTreeNode('e');
        BinaryTreeNode tempTreeF = new BinaryTreeNode('f');
        BinaryTreeNode tempTreeG = new BinaryTreeNode('g');

        // Step 3. Link all nodes.
        tempNodeA.left = tempTreeB;
        tempNodeA.right = tempTreeC;
        tempTreeB.left = tempTreeD;
        tempTreeB.right = tempTreeE;
        tempTreeC.left = tempTreeF;
        tempTreeC.right = tempTreeG;

        resultTree.root = tempNodeA;
        return resultTree;
    }// Of manualConstructTree

    /**
     * 先序遍历
     */
    public void preOrderVisit() {
        preOrderVisit(root);
    }// Of preOrderVisit

    private void preOrderVisit(BinaryTreeNode paraRoot) {
        if (paraRoot != null) {
            System.out.print("" + paraRoot.value + " ");
            preOrderVisit(paraRoot.left);
            preOrderVisit(paraRoot.right);
        }// Of if
    }// Of preOrderVisit

    /**
     * 中序遍历
     */
    public void inOrderVisit() {
        inOrderVisit(root);
    }

    private void inOrderVisit(BinaryTreeNode paraRoot) {
        if (paraRoot != null) {
            inOrderVisit(paraRoot.left);
            System.out.print("" + paraRoot.value + " ");
            inOrderVisit(paraRoot.right);
        }// Of if
    }// Of inOrderVisit

    /**
     * 后序遍历
     */
    public void postOrderVisit() {
        postOrderVisit(root);
    }

    private void postOrderVisit(BinaryTreeNode paraRoot) {
        if (paraRoot != null) {
            postOrderVisit(paraRoot.left);
            postOrderVisit(paraRoot.right);
            System.out.print("" + paraRoot.value + " ");
        }// Of if
    }// Of postOrderVisit

    // 计算树的高度
    public int getDepth() {
        return getDepth(root);
    }

    private int getDepth(BinaryTreeNode paraRoot) {
        return paraRoot == null ? 0 : 1 + Math.max(getDepth(paraRoot.left), getDepth(paraRoot.right));
    }

    /**
     * Get the number of nodes.
     *
     * @return The number of nodes.
     */
    public int getNumNodes() {
        return getNumNodes(root);
    }

    private int getNumNodes(BinaryTreeNode paraRoot) {
        if (paraRoot == null) {
            return 0;
        } else {
            return 1 + getNumNodes(paraRoot.left) + getNumNodes(paraRoot.right);
        }
    }// Of getNumNodes

    /**
     * The entrance of the program.
     *
     * @param args Not used now.
     */
    public static void main(String[] args) {
        BinaryCharTree tree = manualConstructTree();
        System.out.println("The tree's depth is: " + tree.getDepth());

        System.out.print("preOrderVisit is: ");
        tree.preOrderVisit();
        System.out.println();

        System.out.print("inOrderVisit is: ");
        tree.inOrderVisit();
        System.out.println();

        System.out.print("postOrderVisit is: ");
        tree.postOrderVisit();

        System.out.println("\nThe number of nodes is: " + tree.getNumNodes());
    }// Of main
}// Of class BinaryCharTree

老师原本的意思不要结点类,但是加上之后我感觉操作会顺滑一点(也可能是我太菜了)。比如递归遍历和求高之类的直接用判断根节点空,个人感觉比较简洁一些吧。

但是老师的代码里面那样没有结点类的话,怎么表示空树,新建一个二叉树对象就要传进去一个结点值,那一开始就不空了...

下面附上老师的代码

package datastructure.tree;

import java.util.Arrays;
/**
 * Binary tree with char type elements.
 * 
 * @author Fan Min minfanphd@163.com.
 */

public class BinaryCharTree {

	/**
	 * The value in char.
	 */
	char value;

	/**
	 * The left child.
	 */
	BinaryCharTree leftChild;

	/**
	 * The right child.
	 */
	BinaryCharTree rightChild;

	/**
	 *********************
	 * The first constructor.
	 * 
	 * @param paraName
	 *            The value.
	 *********************
	 */
	public BinaryCharTree(char paraName) {
		value = paraName;
		leftChild = null;
		rightChild = null;
	}// Of the constructor

	/**
	 *********************
	 * Manually construct a tree. Only for testing.
	 *********************
	 */
	public static BinaryCharTree manualConstructTree() {
		// Step 1. Construct a tree with only one node.
		BinaryCharTree resultTree = new BinaryCharTree('a');

		// Step 2. Construct all nodes. The first node is the root.
		// BinaryCharTreeNode tempTreeA = resultTree.root;
		BinaryCharTree tempTreeB = new BinaryCharTree('b');
		BinaryCharTree tempTreeC = new BinaryCharTree('c');
		BinaryCharTree tempTreeD = new BinaryCharTree('d');
		BinaryCharTree tempTreeE = new BinaryCharTree('e');
		BinaryCharTree tempTreeF = new BinaryCharTree('f');
		BinaryCharTree tempTreeG = new BinaryCharTree('g');

		// Step 3. Link all nodes.
		resultTree.leftChild = tempTreeB;
		resultTree.rightChild = tempTreeC;
		tempTreeB.rightChild = tempTreeD;
		tempTreeC.leftChild = tempTreeE;
		tempTreeD.leftChild = tempTreeF;
		tempTreeD.rightChild = tempTreeG;

		return resultTree;
	}// Of manualConstructTree

	/**
	 *********************
	 * Pre-order visit.
	 *********************
	 */
	public void preOrderVisit() {
		System.out.print("" + value + " ");

		if (leftChild != null) {
			leftChild.preOrderVisit();
		} // Of if

		if (rightChild != null) {
			rightChild.preOrderVisit();
		} // Of if
	}// Of preOrderVisit

	/**
	 *********************
	 * In-order visit.
	 *********************
	 */
	public void inOrderVisit() {
		if (leftChild != null) {
			leftChild.inOrderVisit();
		} // Of if

		System.out.print("" + value + " ");

		if (rightChild != null) {
			rightChild.inOrderVisit();
		} // Of if
	}// Of inOrderVisit

	/**
	 *********************
	 * Post-order visit.
	 *********************
	 */
	public void postOrderVisit() {
		if (leftChild != null) {
			leftChild.postOrderVisit();
		} // Of if

		if (rightChild != null) {
			rightChild.postOrderVisit();
		} // Of if

		System.out.print("" + value + " ");
	}// Of postOrderVisit

	/**
	 *********************
	 * Get the depth of the binary tree.
	 * 
	 * @return The depth. It is 1 if there is only one node, i.e., the root.
	 *********************
	 */
	public int getDepth() {
		// It is a leaf.
		if ((leftChild == null) && (rightChild == null)) {
			return 1;
		} // Of if

		// The depth of the left child.
		int tempLeftDepth = 0;
		if (leftChild != null) {
			tempLeftDepth = leftChild.getDepth();
		} // Of if

		// The depth of the right child.
		int tempRightDepth = 0;
		if (rightChild != null) {
			tempRightDepth = rightChild.getDepth();
		} // Of if

		// The depth should increment by 1.
		if (tempLeftDepth >= tempRightDepth) {
			return tempLeftDepth + 1;
		} else {
			return tempRightDepth + 1;
		} // Of if
	}// Of getDepth

	/**
	 *********************
	 * Get the number of nodes.
	 * 
	 * @return The number of nodes.
	 *********************
	 */
	public int getNumNodes() {
		// It is a leaf.
		if ((leftChild == null) && (rightChild == null)) {
			return 1;
		} // Of if

		// The number of nodes of the left child.
		int tempLeftNodes = 0;
		if (leftChild != null) {
			tempLeftNodes = leftChild.getNumNodes();
		} // Of if

		// The number of nodes of the right child.
		int tempRightNodes = 0;
		if (rightChild != null) {
			tempRightNodes = rightChild.getNumNodes();
		} // Of if

		// The total number of nodes.
		return tempLeftNodes + tempRightNodes + 1;
	}// Of getNumNodes

	/**
	 *********************
	 * The entrance of the program.
	 * 
	 * @param args
	 *            Not used now.
	 *********************
	 */
	public static void main(String args[]) {
		BinaryCharTree tempTree = manualConstructTree();
		System.out.println("\r\nPreorder visit:");
		tempTree.preOrderVisit();
		System.out.println("\r\nIn-order visit:");
		tempTree.inOrderVisit();
		System.out.println("\r\nPost-order visit:");
		tempTree.postOrderVisit();

		System.out.println("\r\n\r\nThe depth is: " + tempTree.getDepth());
		System.out.println("The number of nodes is: " + tempTree.getNumNodes());
	}// Of main

}// Of BinaryCharTree

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值