算法练习day11——190329(平衡二叉树、搜索二叉树、完全二叉树)
1.平衡二叉树
判断一棵树是否为平衡二叉树
1.1 分析
首先需要得到一个节点的以下四个信息:
- 左子树是否平衡;
- 右子树是否平衡;
- 左子树的高度;
- 右子树的高度。
接着,设计递归:
- 应该返回以此节点为根的树是否平衡,以及此树的高度
- 平衡:
- 它的左右子树都平衡;
- 它的左右子树高度差不超过1;
- 树高:
- 子树中高度较大的值+1;
- 平衡:
注:空树是平衡的。
1.2 代码实现
package Tree;public class BalancedTree {public static class ReturnData{public boolean isB;public int h;public ReturnData(boolean isB, int h) {this.isB=isB;this.h=h;}}public static void main(String[] args) {Node head = new Node(1);head.left = new Node(2);head.right = new Node(3);head.left.left = new Node(4);head.left.right = new Node(5);head.right.left = new Node(6);head.right.right = new Node(7);System.out.println(isBalanced(head).isB);}public static ReturnData isBalanced(Node head) {if(head==null)return new ReturnData(true,0);ReturnData leftData=isBalanced(head.left); if(!leftData.isB)//若左子树不平衡,则后面的不用计算;一路向上返回false//不平衡后,高度无所谓了。return new ReturnData(false,0);ReturnData rightData=isBalanced(head.right); if(!rightData.isB)return new ReturnData(false,0);if(Math.abs(leftData.h-rightData.h)>1)return new ReturnData(false,0); return new ReturnData(true,Math.max(leftData.h, rightData.h)+1);}
}
平衡树是为了解决效率问题
2.搜索二叉树
左子树的值都比节点值小,右子树的值都比节点值大。
通常,搜索二叉树中是不会出现重复节点的。
- 若出现了,一般把相同的压入一个节点,节点值所带的信息可以存入一个list中。
- 需要的话可以记录下重复次数。
2.1 分析
判断一棵树是不是搜索二叉树:如果它的中序遍历序列,节点值是升序的,则是搜索二叉树。
只要将中序遍历的非递归实现中输出节点的语句改为判断当前值是否大于前一个值的语句即可。
要考虑怎么将之前的值存下来。
2.2 代码实现
package Tree;import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;public class BinarySearchTree {public static void main(String[] args) {Node head = new Node(4);head.left = new Node(2);head.right = new Node(6);head.left.left = new Node(1);head.left.right = new Node(3);head.right.left = new Node(5);System.out.println(isBST(head));}public static boolean isBST(Node head) {Node cur=null;if(head!=null) {Stack<Node> stack=new Stack<Node>();Queue<Integer> queue=new LinkedList<Integer>();while(!stack.isEmpty()||head!=null) {if(head!=null) {//以节点不为空的条件进来stack.push(head);head=head.left;}else {//以栈不为空的条件进来cur=stack.pop();if(!queue.isEmpty()) if(cur.value<queue.poll())return false;queue.add(cur.value);cur=cur.right;}}}return true;}
}
3.完全二叉树
判断一个二叉树是不是完全二叉树
3.1 分析
首先二叉树按层遍历,
- 如果一个节点右右孩子但是没有左孩子,一定不是完全二叉树;
- 如果一个节点,它不是左右两个孩子都全:则,它后面的节点必须都是叶子节点,否则不是完全二叉树。
- 有左没右(有右没左第一点已排除);
- 没有孩子。
设置一个boolean stage=false。
当当前数通过了第一点验证,进入第二点时,stage=true,此时,后面节点必须都是叶子节点。
3.2 代码实现
public static boolean isCBT(Node head) {if(head==null)return true;Queue<Node> queue=new LinkedList<Node>();boolean leaf=false;Node l=null;Node r=null;queue.add(head);while(!queue.isEmpty()) {head=queue.poll();l=head.left;r=head.right;if((leaf&&(l!=null||r!=null))||(l==null&&r!=null))//开启了第二阶段(后面的节点必须为空),但是有一个节点不为空;//第一阶段:左为空,右不为空//则返回falsereturn false;if(l!=null)queue.add(l);if(r!=null)queue.add(r);if(l==null||r==null)leaf=true;}return true;
}
用二叉树实现堆结构与数组实现堆结构的比较
二叉树实现没有空间浪费,没有扩容代价。
3.3 已知一棵完全二叉树, 求其节点的个数
要求: 时间复杂度低于O(N), N为这棵树的节点个数
3.3.1 分析
结论:一棵高的满二叉树,节点个数为。
首先遍历以当前节点形成的一棵完全二叉树的左边界,得到此树的高度。——
遍历当前节点右子树的左边界,看它到没到最后一层。——
- 到了最后一层,则说明根节点的左子树是满的;
- 可得到左子树的节点个数;
- 加上当前节点:
- 再递归求右子树(也是一棵完全二叉树,和母问题等效)的节点个数。
- 没到最后一层,说明右子树是一棵满二叉树(高度=左子树高度-1);
- 右树的节点;
- 加上当前节点:;
- 再递归求左子树(也是一棵完全二叉树,和母问题等效)的节点个数。
3.3.2 代码实现
package Tree;import Tree.Test.Node;public class CountNode {public static void main(String[] args) {Node head = new Node(1);head.left = new Node(2);head.right = new Node(3);head.left.left = new Node(4);head.left.right = new Node(5);head.right.left = new Node(6);System.out.println(countNode(head));}public static int countNode(Node head) {if(head==null)return 0;return bs(head,1,mostLevel(head,1));}public static int bs(Node node, int level, int h) {if(level==h)//node为叶子节点return 1;if(mostLevel(node.right,level+1)==h)//右子树最左节点的深度到达最深(即到达最后一层)//左子树为满二叉树,递归右子树//return (1 << (h - level)) +bs(node.right,level+1,h);return (int) (Math.pow(2,(h-level))+bs(node.right,level+1,h));else //右子树为满二叉树,递归左子树return (int) (Math.pow(2,(h-level-1))+bs(node.left,level+1,h));//return (1 << (h - level - 1))+bs(node.left,level+1,h);}public static int mostLevel(Node head,int h) {while(head!=null) {h++;head=head.left;}return h-1;}
}
时间复杂度:
- 每一层需要遍历一个节点
- 要么左子树的根节点,要么右子树的根节点
- 总共层
- 每个节点需要求高度,也是
算法练习day11——190329(平衡二叉树、搜索二叉树、完全二叉树)相关推荐
- 平衡二叉树搜索二叉树
设n(h)表示为高度为h的平衡二叉树的最小节点数,则 n(h) = n(h-1) + n(h-2) + 1,也就是高度为h-1的平衡树最少节点数+高度为h-2的最小节点数+1 . 这点类似于fibol ...
- 有苦有乐的算法 --- 判断一颗二叉树是否是完全二叉树、是否是平衡二叉树、是否是搜索二叉树
是否是完全二叉树 完全二叉树:二叉树的每一层要么是满的,要么从左到右处在变满的路上. public static boolean isCBT(Node head) {if (head == null) ...
- 判断一棵二叉树是否为搜索二叉树、完全二叉树、平衡二叉树(java)
平衡二叉树的解法:主要是求出二叉树的高度,若根节点的左子树的高度与右子树的高度差小于等于1,则表示该二叉树为平衡二叉树 public static class Node{public int valu ...
- 数据结构与算法之判断一棵树是否为搜索二叉树、判断一棵树是否是完全二叉树
数据结构与算法之判断一棵树是否为搜索二叉树.判断一棵树是否是完全二叉树 目录 判断一棵树是否为搜索二叉树 判断一棵树是否是完全二叉树 1. 判断一棵树是否为搜索二叉树 概念:搜索树就是中序遍历的结果是 ...
- C++实现二叉树相关问题(先序遍历,中序遍历,后序遍历,层序遍历,搜索二叉树、平衡二叉树、满二叉树、完全二叉树的判断,最低公共祖先,二叉树的序列化和反序列化)
目录 题目一 二叉树递归和非递归遍历 题目二 如何完成二叉树的宽度(也叫层序)遍历(常见题目:求一棵二叉树的宽度) 题目四 如何判断一棵二叉树是搜索二叉树(BST)? 题目四 如何判断一棵二叉树是平衡 ...
- 算法(63)-二叉树的递归-搜索二叉树-满二叉树-平衡二叉树-
目录 1.二叉树 2.搜索二叉树: 3.满二叉树: 4.平衡二叉树 1.二叉树 先.中.后序遍历 先序(中.左.右):1,2,4,5,3,6,7 中序(左.中.右):4,2,5,1,6,3 ...
- 判断一颗二叉树是否为搜索二叉树和完全二叉树
搜索二叉树:二叉树的中序遍历,在遍历的过程中,节点值都是递增的 class Node(object):def __init__(self,value):self.value = valueself.r ...
- 牛客题霸 [ 判断一棵二叉树是否为搜索二叉树和完全二叉树] C++题解/答案
牛客题霸 [ 判断一棵二叉树是否为搜索二叉树和完全二叉树] C++题解/答案 题解: 搜索二叉树满足以下性质: 1.非空左子树的所以键值小于其根节点的键值 2.非空右子树的所有键值大于其根节点的键值 ...
- 已知一棵完全二叉树存于顺序表sa中,sa.elem[1..sa.length]含结点值,试编写算法由此顺序存储结构建立该二叉树的二叉链表。
已知一棵完全二叉树存于顺序表sa中,sa.elem[1-sa.length]含结点值,试编写算法由此顺序存储结构建立该二叉树的二叉链表. 分析:由二叉树的性质可知,一个下标为i的节点若有左子树,则其左 ...
最新文章
- AttributeError: 'dict' object has no attribute 'status_code'
- html5 minlength,HTML5中是否有minlength验证属性?
- SQL Server 2008不能修改表的解决方法
- 从拼多多分享文案中,我们学会了什么?
- [原创]FineUI秘密花园(二十四) — 树控件之数据绑定
- 将二叉树的叶子结点转换成单链表,并返回最左叶子结点的地址(链头)
- boost::regex模块部分正则表达式迭代相关的测试程序
- 详解Dart中如何通过注解生成代码
- MySQL中EXPLAIN详解
- RTT的线程同步篇——事件
- Android 设备上可以实现 3D Touch 吗?| 原力计划
- c语言中同级运算符的运算顺序,二 如何学习C语言的运算符和运算顺序
- Google的“那些事”
- android pickerview 多行,Android-PickerView系列之介绍与使用篇(一)
- windows下namp的基本操作命令
- 关于Hbase手动实现Major Compact的办法
- 今天是愚人节。(Today is April Fools' Day.)网页需要倾斜o(∩_∩)o
- 1.6 建立Servers服务(2020-12-6)
- 中国数据量占全球27.8%!安防能否借机“回血”?
- Java分割PDF文件(itextpdf)
热门文章
- mysql online ddl
- Spring Security 入门(3-11)Spring Security 的使用-自定义登录验证和回调地址
- AE After Effect 如何分段渲染
- oracle表空间和用户的创建、修改、授权、查看等执行SQL
- xutils,afinal的数据库升级要注意的地方
- 技巧打开网页进行客户个性化信息提交(代码编写)
- apache动态编译/静态编译区别
- java mysql开发_Java数据库开发
- mysql创建唯一索引_mysql创建唯一索引
- 重磅开源!推荐一个以最优惠的方式购买极客时间课程的开源项目!