您的位置:首页 > 其它

判断二叉树是否是平衡二叉树 及二叉树各种操作汇总

2016-07-18 21:27 405 查看
一,问题描述

任意给定一棵二叉树,判断它是否是平衡二叉树。所谓平衡二叉树,是指二叉树中任意一个结点的左右子树的高度之差不超过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层结点的个数

比较两棵二叉--(比较两棵二叉是否相同/判断一棵二叉是否是另一棵二叉的子树)

给定一个序列,判断该序列是否为二叉查找的后序遍历序列

二叉的操作之统计二叉中节点的个数

二叉中的和为某一值的路径

求解二叉中两个结点的最低公共父结点

二叉的先序遍历和后序遍历的应用--输出文件和统计目录大小

二叉查找的递归实现及递归分析

求解二叉树镜像
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: