vlambda博客
学习文章列表

算法总结:左神class5—二叉树是否是平衡二叉树,搜索二叉树,平衡二叉树

二叉树实现堆,增删改查都是O(LOGN),没有扩容代价

一 判断一棵二叉树是否是平衡二叉树(AVL)任何一个节点的左右子树高度只差 <=1

大流程:以每个节点的树都是平衡的,则整棵树就是平衡的。

对于某个节点,需要收集信息:

1 左树是否平衡?否直接faulse;

2 是,同理判断右数是否平衡;

3 两子树都平衡,判断两子树的高度差 <=1?

(套路化操作:列出可能性之后,写代码非常简单)

【优化】树形BP:在二叉树上做动态规划---进阶班

                                                

二  判断是否是搜索二叉树(BST,Binary Search Tree)二叉排序树,二叉查找树:对于一棵树上任何一个节点的子树,左子树 < 节点 < 右子树 。通常不出现重复节点,如果有重复节点,可以把它们的值压缩在一 个节点的内部。

一个二叉树的中序遍历结果依次升序的,则为搜索二叉树(一般搜索二叉树不含重复节点)中序非递归遍历打印的时机来判断是否比上一个node大

红黑树、平衡搜索二叉树(AVL树)等,其实都是搜索二叉树的不同实现。


三  判断是否为完全二叉树CBT,Complete Binary Tree):

堆就是一个完全二叉树。不过堆使用数组位置对应出来的。完全二叉树是指除了最后一层之外,其他每一层的节点数都是满的。最后一层如果也满了,是一颗满二叉树,也是完全二叉树。最后一层如果不满,缺少的节点也全部的集中在右边,那也是一颗完全二叉树。

广度优先遍历 遍历

  1. 一个节点只有右孩子没有左孩子,则非完全二叉树,

  2. 一个节点有左没右或者两个都没有,后面的所有节点都是叶节点,则为完全二叉树

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(true0);// 空树高度为0的平衡树 } ReturnData leftData = process(head.left); if (!leftData.isB) {// 左不平衡直接faulse return 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)); //true System.out.println(isBST1(head)); //true System.out.println(isBST2(head)); //true System.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; }}