二叉树(Binary Tree)

本文详细解析了二叉树的基本概念,包括满二叉树、完全二叉树的定义及其性质,并通过Java代码展示了二叉树的构建、遍历及多种计算方法,如求深度、节点数量等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉树是n个结点所构成的集合,它或为空树或为非空树。

对于非空树T:1.有且仅有一个称之为根的结点;2.除根节点之外的其余结点分为两个互不相交的子集T1和T2,分别称为左子树和右子树,且T1和T2也都是二叉树。

满二叉树:深度为k且含有2^{k}-1个节点的二叉树。

完全二叉树:深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1-n的结点一一对应,称之为完全二叉树。

    

二叉树的性质

1.在二叉树的第i层上至多有2^{i-1}个结点(i >= 1)。

2.深度为k的二叉树至多有2^{k}-1个结点(k >= 1)。

3.对任何一颗二叉树T,若其终端节点数(叶子节点数)为a ,度(结点拥有的子树数)为2的节点数为b ,则 a = b + 1

4.具有n个结点的完全二叉树的深度为floor(\log _{2}n)+1 

5.如果一颗含有n个结点的完全二叉树的结点按层序编号(即从上到下,从左到右编号),如果某个结点的编号为i,那么它的左孩子的编号为2*i ,若2*i > n则表示结点i无左孩子,右孩子的编号为2*i+1

下面是Java实现的二叉树,里面包括 建树,树的遍历,求树的深度,节点个数,树的路径长度,树的带权路径长度,根节点到叶子节点组成的数字之和 

import java.util.Scanner;
/**
 * 二叉树
 * 包括前序,中序,后序遍历
 * 求树的深度,节点个数,树的路径长度,树的带权路径长度,根节点到叶子节点组成的数字之和
 * @author tiny_spot
 *
 */
public class BinaryTree {
	static Scanner s = new Scanner(System.in);
	public static void main(String []args) {
		System.out.println("树的叶子节点的左右节点用0表示,前序输入");
		BiTree root = new BiTree();
		createTree(root);
		preOrder(root);
		System.out.println();
		inOrder(root);
		System.out.println();
		postOrder(root);
		System.out.println();
		System.out.println("深度:"+depth(root));
		System.out.println("节点个数:"+nodeCnt(root));
		System.out.println("数字之和:"+numberSum(root, 0));
		System.out.println("树的路径长度:"+treePathLen(root ,0));
		System.out.println("树的带权路径长度:"+weightPathLen(root ,0));
	}
	/**
	 * 创建二叉树
	 * @param root
	 */
	public static void createTree(BiTree root) {
		int t = s.nextInt();
		root.setData(t);
		if(t == 0)
			return ;
		else {
			root.setData(t);
			root.left = new BiTree();
			createTree(root.left);
			if(root.left.getData() == 0)
				root.left = null;
			root.right = new BiTree();
			createTree(root.right);
			if(root.right.getData() == 0)
				root.right = null;
		}
	}
	/**
	 * 先序遍历
	 * @param root
	 */
	public static void preOrder(BiTree root) {
		if(root == null)
			return;
		System.out.print(root.getData()+" ");
		preOrder(root.left);
		preOrder(root.right);
	}
	/**
	 * 中序遍历
	 * @param root
	 */
	public static void inOrder(BiTree root) {
		if(root == null)
			return;
		inOrder(root.left);
		System.out.print(root.getData()+" ");
		inOrder(root.right);
	}
	/**
	 * 后序遍历
	 * @param root
	 */
	public static void postOrder(BiTree root) {
		if(root == null)
			return ;
		postOrder(root.left);
		postOrder(root.right);
		System.out.print(root.getData()+" ");
	}
	/**
	 * 计算二叉树的深度
	 * @param root
	 * @return 二叉树的深度
	 */
	public static int depth(BiTree root) {
		if(root == null)
			return 0;
		int left = 1+depth(root.left);
		int right = 1+depth(root.right);
		return left > right ? left : right;
	}
	/**
	 * 计算二叉树节点个数
	 * @param root
	 * @return 二叉树节点个数
	 */
	public static int nodeCnt(BiTree root) {
		if(root == null)
			return 0;
		int left = nodeCnt(root.left);
		int right = nodeCnt(root.right);
		return 1+left+right;
	}
	/**
	 * 求所有根到叶子节点组成的数字之和                                 1
	 * 所有路径:1->2->4, 1->2->5, 1->3      2  3
	 * 124+125+13=262                    4  5 
	 * @param root 树的根节点
	 * @param n 一开始的数字
	 * @return 数字之和
	 */
	public static int numberSum(BiTree root ,int n) {
		if(root == null)
			return 0;
		int left = numberSum(root.left , n*10+root.getData());
		int right = numberSum(root.right, n*10+root.getData());
		if(left+right == 0)
			return n*10+root.getData();
		return left + right;
	}
	/**
	 * 求树的路径长度:即从树根到每一个节点的路径长度之和
	 * @param root
	 * @param n
	 * @return 树的路径长度之和
	 */
	public static int treePathLen(BiTree root ,int n) {
		if(root == null)
			return 0;
		int left = treePathLen(root.left ,n+1);
		int right = treePathLen(root.right, n+1);
		return left + right + n;
	}
	/**
	 * 求树的带权路径长度:即树中所有叶子节点的带权路径长度之和
	 * 节点的带权路径长度:从该节点到树根之间的路径长度与节点上权值的乘积
	 * @param root
	 * @param n
	 * @return
	 */
	public static int weightPathLen(BiTree root ,int n) {
		if(root == null)
			return 0;
		int left = weightPathLen(root.left, n+1);
		int right = weightPathLen(root.right, n+1);
		if(left+right == 0)//若左右子树的带权路径长度为0,则说明该节点是叶子节点
			return n*root.getData();
		return left + right;
	}
}
class BiTree{
	public BiTree left = null;
	public BiTree right = null;
	private int data ;
	public void setData(int data) {
		this.data = data;
	}
	public int getData() {
		return data;
	}
}
//1 2 3 0 0 4 5 0 6 0 0 7 0 0 0
//1 2 4 0 0 5 0 0 3 0 0
//1 3 7 0 0 5 0 0 6 2 0 0 4 0 0

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值