二叉树

简单地来说,满足以下两个条件的树就是二叉树:

  1. 本身是有序树;
  2. 树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2;

二叉树和非二叉树的比较图

二叉树的性质

二叉树具有以下几个性质:

  1. 二叉树中,第 i 层最多有 2i-1 个结点。
  2. 如果二叉树的深度为 K,那么此二叉树最多有2K-1 个结点。
  3. 包含n个结点的二叉树的高度至少为(log2n)+1
二叉树还可以继续分类,衍生出满二叉树完全二叉树。 满二叉树
满二叉树

如果二叉树中除了叶子结点,每个结点的度都为 2,则此二叉树称为满二叉树
满二叉树
上图就是一个满二叉树。

满二叉树除了满足普通二叉树的性质,还具有以下性质:

满二叉树中不存在度为 1 的节点,每一个分支点中都两棵深度相同的子树,且叶子节点都在最底层。

完全二叉树
如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树

完全二叉树和非完全二叉树的比较图
像左图就是一个完全二叉树,而右图没有按照从左到右的结构去分布,只能算是一个普通的二叉树。可以看看这篇的 树的结构特性

完全二叉树的特性:

  • 如果一棵完全二叉树的下标为n,那么当n为奇数的时候,它的父节点的下标就为(n+1)*2-1,如果n为偶数的话,那么它的节点的下标就为(n+1)*2。
  • 一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。

对于任意一个结点 i ,完全二叉树还有以下几个结论成立:

  1. 当 i>1 时,父亲结点为结点 [i/2] 。(i=1 时,表示的是根结点,无父亲结点)
  2. 如果 2i>n(总结点的个数,则结点 i 肯定没有左孩子(为叶子结点);否则其左孩子是结点 2i 。
  3. 如果 2i+1>n ,则结点 i 肯定没有右孩子;否则右孩子是结点 2i+1 。

来一个练习题
题目描述:输入一个二叉树,输出其镜像。

/*
 * 题目描述:输入一个二叉树,输出其镜像。
 */
public class Solution {
	Scanner scanner = new Scanner(System.in);
	// 建立二叉树
	public TreeNode createTree(TreeNode root) {
		String val;
		val = scanner.next(); // next方法每次取到一个间隔符前面的数据
		if (val.equals("#")) {
			return null;
		}
		root = new TreeNode(Integer.parseInt(val));
		System.out.println("输入的数据为:" + val);
		root.left = createTree(root.left);
		root.right = createTree(root.right);
		return root;
	}
	// 得到二叉树的镜像 —— 递归的方式
	public void Mirror(TreeNode root) {
		if (root == null) {
			return;
		}
		if ((root.left == null) && (root.right == null)) {
			return;
		}
		TreeNode temp = root.left;
		root.left = root.right;
		root.right = temp;
		Mirror(root.left);
		Mirror(root.right);
	}
	// 得到二叉树的镜像 —— 不使用递归
	public void MirrorNotRecursive(TreeNode root) {
		LinkedList stack = new LinkedList();
		TreeNode temp = null;
		if (root == null) {
			return;
		}
		stack.add(root);
		while (stack.size() != 0) {
			TreeNode node = (TreeNode) stack.removeFirst();
			temp = node.left;
			node.left = node.right;
			node.right = temp;
			if (node.right != null) {
				stack.add(node.right);
			}
			if (node.left != null) {
				stack.add(node.left);
			}
		}
	}
	// 层次遍历二叉树
	public void levelTraverse(TreeNode root) {
		if (root == null) {
			return;
		}
		LinkedList list = new LinkedList();
		list.add(root);
		while (list.size() != 0) {
			TreeNode node = (TreeNode) list.removeFirst(); // list.removeFirst() 该方法LinkedList才有
			System.out.print(node.val + " ");
			if (node.left != null) {
				list.add(node.left);
			}
			if (node.right != null) {
				list.add(node.right);
			}
		}
	}

	public static void main(String[] args) {
		Solution solution = new Solution();
		TreeNode root = null;
		root = solution.createTree(root);
		System.out.println("原二叉树的层次遍历");
		solution.levelTraverse(root);
		solution.Mirror(root);
		System.out.println("\n输出该二叉树的镜像");
		solution.levelTraverse(root);
		solution.MirrorNotRecursive(root);
		System.out.println("\n输出该二叉树的镜像(非递归方式)");
		solution.levelTraverse(root);
	}

}

/*
 * 
 * 测试数据:
 * 
 * 1 2 3 # 4 # # 5 6 # # # 7 8 # # 9 10 # # 11 # # (说明:其中#说明左右子树为空)
 * 
 * 用先序遍历来建立树后,层次遍历结果为: 1 2 7 3 5 8 9 4 6 10 11
 * 
 * 反转二叉树之后:1 7 2 9 8 5 3 11 10 6 4
 * 
 */
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值