判断二叉树是否是平衡二叉树 及二叉树各种操作汇总
2016-07-18 21:27
405 查看
一,问题描述
任意给定一棵二叉树,判断它是否是平衡二叉树。所谓平衡二叉树,是指二叉树中任意一个结点的左右子树的高度之差不超过1
二,思路分析
可以分两步实现。第一步先实现求解 二叉树中每个结点的高度的函数height(BinaryNode );然后先序遍历二叉树中的每一个结点node,调用height()求出该结点的左子树高度height(node.left) 和 右子树高度 height(node.right)。根据左右子树的高度判断是否为平衡二叉树。
求解二叉树高度代码如下:
判断二叉树是否平衡代码如下:
可以看出,这是一个典型的“先序遍历”算法。第4、5、6行相当于先“访问”结点,第9行相当于 再“访问”该结点的左子树,然后再“访问”结点的右子树。
但是,上面的“先序遍历”判断二叉树平衡的方法,时间复杂度比较大。因为,二叉树中的很多结点遍历了多次。
比如,求解根的的高度时,需要先求解根的左子树高度和右子树高度,这就遍历了整棵左子树中的结点和右子树中的结点。而求解以根的左孩子为根的子树的高度时,又需要遍历它(根的左孩子)的左子树和右子树。这样,相当于很多结点的高度重复计算了。
根本原因是采用了“先序遍历”,求根的高度,需要先知道根的左右孩子的高度。
如果采用后序遍历,先知道某结点左右子树的高度,如果左右子树的高度都不满足平衡二叉树(二者高度相减大于1),那么都不需要再去求解该结点的高度了。
因为,平衡二叉树要求二叉树中任意结点的左右子树高度相差不超过1
至于具体代码实现,先不贴了。
三,完整代码实现
View Code
四,二叉树操作汇总
按层打印二叉树--每行打印一层
二叉树的前序、中序、后序的非递归遍历实现
二叉树的层序遍历算法实现求二叉树中第K层结点的个数
比较两棵二叉树--(比较两棵二叉树是否相同/判断一棵二叉树是否是另一棵二叉树的子树)
给定一个序列,判断该序列是否为二叉树查找树的后序遍历序列
二叉树的操作之统计二叉树中节点的个数
二叉树中的和为某一值的路径
求解二叉树中两个结点的最低公共父结点
二叉树的先序遍历和后序遍历的应用--输出文件和统计目录大小
二叉查找树的递归实现及递归分析
求解二叉树镜像
任意给定一棵二叉树,判断它是否是平衡二叉树。所谓平衡二叉树,是指二叉树中任意一个结点的左右子树的高度之差不超过1
二,思路分析
可以分两步实现。第一步先实现求解 二叉树中每个结点的高度的函数height(BinaryNode );然后先序遍历二叉树中的每一个结点node,调用height()求出该结点的左子树高度height(node.left) 和 右子树高度 height(node.right)。根据左右子树的高度判断是否为平衡二叉树。
求解二叉树高度代码如下:
private int height(BinaryNode root){ if(root == null) return 0; int left_height = height(root.left); int right_height = height(root.right); return 1 + (left_height > right_height ? left_height : right_height); }
判断二叉树是否平衡代码如下:
private boolean isBalance(BinaryNode root){ if(root == null) return true; int left_height = height(root.left); int right_height = height(root.right); if(Math.abs(left_height - right_height) > 1) return false; else return isBalance(root.left) && isBalance(root.right); }
可以看出,这是一个典型的“先序遍历”算法。第4、5、6行相当于先“访问”结点,第9行相当于 再“访问”该结点的左子树,然后再“访问”结点的右子树。
但是,上面的“先序遍历”判断二叉树平衡的方法,时间复杂度比较大。因为,二叉树中的很多结点遍历了多次。
比如,求解根的的高度时,需要先求解根的左子树高度和右子树高度,这就遍历了整棵左子树中的结点和右子树中的结点。而求解以根的左孩子为根的子树的高度时,又需要遍历它(根的左孩子)的左子树和右子树。这样,相当于很多结点的高度重复计算了。
根本原因是采用了“先序遍历”,求根的高度,需要先知道根的左右孩子的高度。
如果采用后序遍历,先知道某结点左右子树的高度,如果左右子树的高度都不满足平衡二叉树(二者高度相减大于1),那么都不需要再去求解该结点的高度了。
因为,平衡二叉树要求二叉树中任意结点的左右子树高度相差不超过1
至于具体代码实现,先不贴了。
三,完整代码实现
import java.util.LinkedList; import java.util.Queue; import java.util.Random; public class MyBinaryTree2 { private static final Random rand = new Random();//insert left or right private static class BinaryNode{ int ele; BinaryNode left; BinaryNode right; public BinaryNode(int ele) { this.ele = ele; this.left = this.right = null; } } private BinaryNode root; public void buildTree(){ int[] ndoes = {3,0,7,4,8}; for (int i : ndoes) { insert(i); } } public BinaryNode insert(int ele){ return root = insert(root, ele); } private BinaryNode insert(BinaryNode root, int ele){ if(root == null) return root = new BinaryNode(ele); if(rand.nextInt() %2 == 0) root.left = insert(root.left, ele); else root.right = insert(root.right, ele); return root; } //求解二叉树的高度 public int height(){ return height(root); } private int height(BinaryNode root){ if(root == null) return 0; int left_height = height(root.left); int right_height = height(root.right); return 1 + (left_height > right_height ? left_height : right_height); } //判断二叉树是否为平衡二叉树 public boolean isBalance(){ return isBalance(root); } private boolean isBalance(BinaryNode root){ if(root == null) return true; int left_height = height(root.left); int right_height = height(root.right); if(Math.abs(left_height - right_height) > 1) return false; else return isBalance(root.left) && isBalance(root.right); } //print binary tree in level public void printTree(){ if(root == null) return; printTree(root); } //按层打印二叉树,每行打印一层 private void printTree(BinaryNode root){ assert root != null; Queue<BinaryNode> queue = new LinkedList<MyBinaryTree2.BinaryNode>(); BinaryNode currentNode = root; int current, next; current = 1; next = 0; queue.offer(root); while(!queue.isEmpty()) { currentNode = queue.poll(); System.out.printf("%-4d" ,currentNode.ele); current--; if(currentNode.left != null) { queue.offer(currentNode.left); next++; } if(currentNode.right != null) { queue.offer(currentNode.right); next++; } if(current == 0) { System.out.println(); current = next; next = 0; } } } //test public static void main(String[] args) { MyBinaryTree2 mbt2 = new MyBinaryTree2(); mbt2.buildTree(); mbt2.printTree(); System.out.println("height:" + mbt2.height()); System.out.println("balace? " + mbt2.isBalance()); } }
View Code
四,二叉树操作汇总
按层打印二叉树--每行打印一层
二叉树的前序、中序、后序的非递归遍历实现
二叉树的层序遍历算法实现求二叉树中第K层结点的个数
比较两棵二叉树--(比较两棵二叉树是否相同/判断一棵二叉树是否是另一棵二叉树的子树)
给定一个序列,判断该序列是否为二叉树查找树的后序遍历序列
二叉树的操作之统计二叉树中节点的个数
二叉树中的和为某一值的路径
求解二叉树中两个结点的最低公共父结点
二叉树的先序遍历和后序遍历的应用--输出文件和统计目录大小
二叉查找树的递归实现及递归分析
求解二叉树镜像
相关文章推荐
- 安装icephp 记
- Java中对比两个对象中属性值[反射、注解]
- java活动对象学习总结
- JSON 入门 之 JSON 的语法规则(二)
- 线程池初学
- Linux内核的整体架构
- Semaphore实现信号灯
- Activity
- poj 2057 The Lost House
- SlidingMenu的简单使用
- 阐述ArrayList、Vector、LinkedList的存储性能和特性?
- Android 常用 adb 命令总结
- 水仙花数
- Dlib人脸特征点检测(速度优化)
- Graylog2+mongdb+rsyslog中央日志服务器对syslog的web管理
- 你应该远离的6个Java特性
- 常见的均值不等式的使用技巧
- 统计难题(hdoj1251)
- 奇偶分离
- 常见的面试题总结