算法总结:左神class5—二叉树是否是平衡二叉树,搜索二叉树,平衡二叉树
二叉树实现堆,增删改查都是O(LOGN),没有扩容代价
一 判断一棵二叉树是否是平衡二叉树(AVL):任何一个节点的左右子树高度只差 <=1
大流程:以每个节点的树都是平衡的,则整棵树就是平衡的。
对于某个节点,需要收集信息:
1 左树是否平衡?否直接faulse;
2 是,同理判断右数是否平衡;
3 两子树都平衡,判断两子树的高度差 <=1?
(套路化操作:列出可能性之后,写代码非常简单)
【优化】树形BP:在二叉树上做动态规划---进阶班
二 判断是否是搜索二叉树(BST,Binary Search Tree)二叉排序树,二叉查找树:对于一棵树上任何一个节点的子树,左子树 < 节点 < 右子树 。通常不出现重复节点,如果有重复节点,可以把它们的值压缩在一 个节点的内部。
一个二叉树的中序遍历结果依次升序的,则为搜索二叉树(一般搜索二叉树不含重复节点)中序非递归遍历打印的时机来判断是否比上一个node大
红黑树、平衡搜索二叉树(AVL树)等,其实都是搜索二叉树的不同实现。
三 判断是否为完全二叉树CBT,Complete Binary Tree):
堆就是一个完全二叉树。不过堆使用数组位置对应出来的。完全二叉树是指除了最后一层之外,其他每一层的节点数都是满的。最后一层如果也满了,是一颗满二叉树,也是完全二叉树。最后一层如果不满,缺少的节点也全部的集中在右边,那也是一颗完全二叉树。
广度优先遍历 按层遍历
一个节点只有右孩子没有左孩子,则非完全二叉树,
一个节点有左没右或者两个都没有,后面的所有节点都是叶节点,则为完全二叉树
import java.util.LinkedList;import java.util.Queue;import java.util.Stack;public class Code_07_IsBSTAndCBT {public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}//一.递归判断是否是平衡二叉树public static class ReturnData {public boolean isB;// 是否平衡public int h;// 高度public ReturnData(boolean isB, int h) {// 基本初始化this.isB = isB;this.h = h;}}// 递归跑 主函数 后序遍历public static Boolean isB(Node head) {return process(head).isB;}public static ReturnData process(Node head) {if (head == null) {return new ReturnData(true, 0);// 空树高度为0的平衡树}ReturnData leftData = process(head.left);if (!leftData.isB) {// 左不平衡直接faulsereturn new ReturnData(false, 0);// 只要不平衡,高度值没用,随意随便写}ReturnData rightData = process(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);// 左树高度和右数高度大1的高度即为整棵树高度}//二.递归判断是否是二叉搜索树int pre = Integer.MIN_VALUE;public static Boolean isBST1(Node head) {boolean res = true;if (head == null) {return res;}isBST1(head.left);if (head.value > pre) {pre = head.value;} else {res = false;}isBST1(head.right);return res;}//非递归morris遍历public static Boolean isBST2(Node head) {int pre = Integer.MIN_VALUE;boolean res = true;if (head != null) {Stack<Node> stack = new Stack<Node>();while (!stack.isEmpty() || head != null) {if (head != null) {stack.push(head);head = head.left;} else {head = stack.pop();// 下面的if else 相当于// System.out.print(head.value + "");// 打印时机替换成比较时机,用一个变量记住上一次的值来判断是否为中序遍历升序if (head.value > pre) {pre = head.value;} else {res = false;}head = head.right;}}}return res;System.out.printIn();}//三.判断是否是完全二叉树public static boolean isCBT(Node head) {if (head == null) {return true;}//LinkedList是双端链表,可以实现队列结构Queue<Node> queue = new LinkedList<Node>();boolean leaf = false;Node l = null;Node r = null;queue.offer(head);while (!queue.isEmpty()) {head = queue.poll();l = head.left;// 判断完全二叉树的两个标准:// ①某个节点有右孩子没有左孩子,则不是完全二叉树// ②满足①的条件下,某个节点没有右孩子有左孩子,// 或者没有左右孩子时,后面遇到的所有节点必须是叶节点。if ((leaf && (l != null || r != null))||(l == null && r != null)) {return false;}if (l != null) {queue.offer(l);// 宽度遍历先压左}if (r != null) {queue.offer(r);// 再压右}if (l == null || r == null) {leaf = true;}}return true;}// for test -- print tree 直观打印public static void printTree(Node head) {System.out.println("Binary Tree:");printInOrder(head, 0, "H", 17);System.out.println();}public static void printInOrder(Node head, int height, String to, int len) {if (head == null) {return;}printInOrder(head.right, height + 1, "v", len);String val = to + head.value + to;int lenM = val.length();int lenL = (len - lenM) / 2;int lenR = len - lenM - lenL;val = getSpace(lenL) + val + getSpace(lenR);System.out.println(getSpace(height * len) + val);printInOrder(head.left, height + 1, "^", len);}public static String getSpace(int num) {String space = " ";StringBuffer buf = new StringBuffer("");for (int i = 0; i < num; i++) {buf.append(space);}return buf.toString();}public static void main(String[] args) {Node head = new Node(5);head.left = new Node(3);head.right = new Node(8);head.left.left = new Node(2);head.left.right = new Node(4);head.right.left = new Node(6);head.right.right = new Node(10);head.left.left.left = new Node(1);head.right.left.right = new Node(7);head.right.right.left = new Node(9);printTree(head);System.out.println(isB(head)); //trueSystem.out.println(isBST1(head)); //trueSystem.out.println(isBST2(head)); //trueSystem.out.println(isCBT(head)); //false}}
public class IsBalanced2 {public boolean IsBalanced_Solution(TreeNode root) {return getDepth(root) != -1;}private int getDepth(TreeNode root) {if (root == null)return 0;int leftDepth = getDepth(root.left);if (leftDepth == -1) {return -1;}int rightDepth = getDepth(root.right);if (rightDepth == -1) {return -1;}return Math.abs(leftDepth - rightDepth) > 1 ? -1 : Math.max(leftDepth, rightDepth) + 1;}}
