pull/3/head
parent
389df193c9
commit
f01fe6cc76
@ -0,0 +1,241 @@
|
|||||||
|
package leo.class08_12;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName IsBST
|
||||||
|
* @DATE 2020/12/11 6:05 下午
|
||||||
|
* @Description 判读是否是搜索二叉树
|
||||||
|
* 每棵树的左部分比自己小, 右部分比自己大
|
||||||
|
* 经典搜索二叉树没有重复值
|
||||||
|
* 1.Left subtree is Binary Search Tree
|
||||||
|
* 2.right subtree is Binary Search Tree
|
||||||
|
* 3.max value of left subtree less than the value of head
|
||||||
|
* 4.min value of right subtree greater than the value of head
|
||||||
|
*/
|
||||||
|
public class IsBST {
|
||||||
|
|
||||||
|
static class Code {
|
||||||
|
public static boolean isBST(Node head){
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return process(head).is;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Info process(Node node) {
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
|
||||||
|
boolean is = true;
|
||||||
|
int max = node.value;
|
||||||
|
int min = node.value;
|
||||||
|
if (left != null) {
|
||||||
|
max = Math.max(max, left.max);
|
||||||
|
min = Math.min(min, left.min);
|
||||||
|
}
|
||||||
|
if (right != null) {
|
||||||
|
min = Math.min(min, right.min);
|
||||||
|
max = Math.max(max, right.max);
|
||||||
|
}
|
||||||
|
if (left != null && !left.is) {
|
||||||
|
is = false;
|
||||||
|
}
|
||||||
|
if (right != null && !right.is) {
|
||||||
|
is = false;
|
||||||
|
}
|
||||||
|
if (left != null && left.max >= node.value) {
|
||||||
|
is = false;
|
||||||
|
}
|
||||||
|
if (right != null && right.min <= node.value) {
|
||||||
|
is = false;
|
||||||
|
}
|
||||||
|
return new Info(is, max, min);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Info{
|
||||||
|
boolean is;
|
||||||
|
int max;
|
||||||
|
int min;
|
||||||
|
public Info(boolean is,int max,int min){
|
||||||
|
this.is = is;
|
||||||
|
this.max = max;
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Code1{
|
||||||
|
public static boolean isBST(Node head){
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return process(head).isBST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
boolean isBST = true;
|
||||||
|
int max = node.value;
|
||||||
|
int min = node.value;
|
||||||
|
if (left != null) {
|
||||||
|
max = Math.max(max, left.max);
|
||||||
|
min = Math.min(min, left.min);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (right != null) {
|
||||||
|
max = Math.max(max, right.max);
|
||||||
|
min = Math.min(min, right.min);
|
||||||
|
}
|
||||||
|
if (left != null && !left.isBST) {
|
||||||
|
isBST = false;
|
||||||
|
}
|
||||||
|
if (right != null && !right.isBST) {
|
||||||
|
isBST = false;
|
||||||
|
}
|
||||||
|
if (left != null && left.max >= node.value) {
|
||||||
|
isBST = false;
|
||||||
|
}
|
||||||
|
if (right != null && right.min <= node.value) {
|
||||||
|
isBST = false;
|
||||||
|
}
|
||||||
|
return new Info(isBST, max, min);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static class Info{
|
||||||
|
boolean isBST;
|
||||||
|
int max;
|
||||||
|
int min;
|
||||||
|
public Info(boolean is,int ma,int mi){
|
||||||
|
this.isBST = is;
|
||||||
|
this.max = ma;
|
||||||
|
this.min = mi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Code2{
|
||||||
|
public static boolean isBST(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return process(head).isBST;
|
||||||
|
}
|
||||||
|
public static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
boolean isBST = false;
|
||||||
|
int max = node.value;
|
||||||
|
int min = node.value;
|
||||||
|
if (left != null) {
|
||||||
|
max = Math.max(max, left.max);
|
||||||
|
min = Math.min(min, left.min);
|
||||||
|
}
|
||||||
|
if (right != null) {
|
||||||
|
max = Math.max(max, right.max);
|
||||||
|
min = Math.min(min, right.min);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(left == null ? true : left.isBST)
|
||||||
|
&& (right == null ? true : right.isBST)
|
||||||
|
&& (left == null ? true : left.max < node.value)
|
||||||
|
&& (right == null ? true : right.min > node.value)
|
||||||
|
) {
|
||||||
|
isBST = true;
|
||||||
|
}
|
||||||
|
return new Info(isBST, max, min);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class Info{
|
||||||
|
boolean isBST;
|
||||||
|
int max;
|
||||||
|
int min;
|
||||||
|
public Info(boolean is,int ma,int mi){
|
||||||
|
this.isBST = is;
|
||||||
|
this.max = ma;
|
||||||
|
this.min = mi;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class Logarithm{
|
||||||
|
public static boolean isBST(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ArrayList<Node> list = new ArrayList<>();
|
||||||
|
in(head, list);
|
||||||
|
for (int i = 1; i < list.size(); i++) {
|
||||||
|
if (list.get(i).value <= list.get(i - 1).value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void in(Node node, ArrayList<Node> list) {
|
||||||
|
if (node == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
in(node.left, list);
|
||||||
|
list.add(node);
|
||||||
|
in(node.right, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
int level = 4;
|
||||||
|
int range = 100;
|
||||||
|
int test = 100000;
|
||||||
|
System.out.println("start!");
|
||||||
|
for (int i = 0; i < test; i++) {
|
||||||
|
Node head = generateRandomNode(level, range);
|
||||||
|
boolean codec = Code2.isBST(head);
|
||||||
|
boolean logarithm = Logarithm.isBST(head);
|
||||||
|
if (codec != logarithm) {
|
||||||
|
System.out.println("fuck!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("end!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node generateRandomNode(int level, int range) {
|
||||||
|
return generate(1, level, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Node generate(int i, int n, int range) {
|
||||||
|
if (i > n || Math.random() < 0.5) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node head = new Node((int) (range * Math.random()));
|
||||||
|
head.left = generate(i + 1, n, range);
|
||||||
|
head.right = generate(i + 1, n, range);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,178 @@
|
|||||||
|
package leo.class08_12;
|
||||||
|
|
||||||
|
import com.sun.deploy.security.TrustRecorder;
|
||||||
|
|
||||||
|
import java.net.HttpRetryException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName IsBalanced
|
||||||
|
* @DATE 2020/12/11 3:57 下午
|
||||||
|
* @Description
|
||||||
|
* 判断是否是平衡二叉树
|
||||||
|
* 每一颗子树的左右高的相差的绝对值不超过一
|
||||||
|
* 1.是否是平衡
|
||||||
|
* 2.当前树的高度
|
||||||
|
*/
|
||||||
|
public class IsBalanced {
|
||||||
|
|
||||||
|
static class Code {
|
||||||
|
public static boolean isBalanced(Node head) {
|
||||||
|
return process(head).isBalanced;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Info process(Node node) {
|
||||||
|
if (node == null) {
|
||||||
|
return new Info(true, 0);
|
||||||
|
}
|
||||||
|
Info leftInfo = process(node.left);
|
||||||
|
Info rightInfo = process(node.right);
|
||||||
|
boolean isBalanced = true;
|
||||||
|
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
|
||||||
|
if (!leftInfo.isBalanced || !rightInfo.isBalanced||Math.abs(leftInfo.height - rightInfo.height) > 1) {
|
||||||
|
isBalanced = false;
|
||||||
|
}
|
||||||
|
return new Info(isBalanced, height);
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 以当前节点为头判断是否为平衡二叉树
|
||||||
|
*/
|
||||||
|
static class Info{
|
||||||
|
boolean isBalanced;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
public Info(boolean b, int h) {
|
||||||
|
this.isBalanced = b;
|
||||||
|
this.height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Code1 {
|
||||||
|
public static boolean isBalanced(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return process(head).isBalanced;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return new Info(true, 0);
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
boolean is = true;
|
||||||
|
int height = Math.max(left.height, right.height) + 1;
|
||||||
|
if (!left.isBalanced || !right.isBalanced || Math.abs(right.height - left.height) > 1) {
|
||||||
|
is = false;
|
||||||
|
}
|
||||||
|
return new Info(is, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Info{
|
||||||
|
boolean isBalanced;
|
||||||
|
int height;
|
||||||
|
public Info(boolean is,int h){
|
||||||
|
this.isBalanced = is;
|
||||||
|
this.height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Code2{
|
||||||
|
static boolean isBalanced(Node head){
|
||||||
|
return process(head).isBalanced;
|
||||||
|
}
|
||||||
|
static Info process(Node node) {
|
||||||
|
if (node == null) {
|
||||||
|
return new Info(true, 0);
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
boolean isBalanced = true;
|
||||||
|
int height = Math.max(left.height, right.height) + 1;
|
||||||
|
if (!left.isBalanced || !right.isBalanced || Math.abs(right.height - left.height) > 1) {
|
||||||
|
isBalanced = false;
|
||||||
|
}
|
||||||
|
return new Info(isBalanced, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Info{
|
||||||
|
boolean isBalanced;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
public Info(boolean is, int h) {
|
||||||
|
this.isBalanced = is;
|
||||||
|
this.height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Logarithm{
|
||||||
|
public static boolean isBalanced(Node head) {
|
||||||
|
boolean[] ans = new boolean[1];
|
||||||
|
ans[0] = true;
|
||||||
|
process(head, ans);
|
||||||
|
|
||||||
|
return ans[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int process(Node head, boolean[] ans) {
|
||||||
|
if (!ans[0] || head == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int leftHeight = process(head.left, ans);
|
||||||
|
int rightHeight = process(head.right, ans);
|
||||||
|
if (Math.abs(leftHeight - rightHeight) > 1) {
|
||||||
|
ans[0] = false;
|
||||||
|
}
|
||||||
|
return Math.max(leftHeight, rightHeight) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
|
||||||
|
int test = 10000;
|
||||||
|
int level = 4;
|
||||||
|
int range = 100;
|
||||||
|
System.out.println("Start!");
|
||||||
|
for (int i = 0; i < test; i++) {
|
||||||
|
Node head = generateRandomNode(level, range);
|
||||||
|
boolean codec = Code2.isBalanced(head);
|
||||||
|
boolean logarithm = IsBalanced.Logarithm.isBalanced(head);
|
||||||
|
if (codec != logarithm) {
|
||||||
|
System.out.println("fuck!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("End!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node generateRandomNode(int level, int range) {
|
||||||
|
|
||||||
|
return generateRandomNode(1, level, range);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node generateRandomNode(int curLevel, int level, int range) {
|
||||||
|
if (curLevel > level || Math.random() < 0.5) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node head = new Node((int) (range * Math.random()));
|
||||||
|
head.left = generateRandomNode(curLevel + 1, level, range);
|
||||||
|
head.right = generateRandomNode(curLevel + 1, level, range);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,169 @@
|
|||||||
|
package leo.class08_12;
|
||||||
|
|
||||||
|
import javax.swing.plaf.TreeUI;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName IsCBT
|
||||||
|
* @DATE 2020/12/11 3:22 下午
|
||||||
|
* @Description
|
||||||
|
* 判断二叉树是否是完全二叉树
|
||||||
|
* 1.如果一个树只有右节点没有左节点 直接false
|
||||||
|
* 2.当第一次遇到左右不双全的树时,剩下的节点必须是叶节点
|
||||||
|
*/
|
||||||
|
public class IsCBT {
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
int level = 4;
|
||||||
|
int range = 100;
|
||||||
|
int testTime = 10000;
|
||||||
|
System.out.println("start");
|
||||||
|
|
||||||
|
for (int i = 0; i < testTime; i++) {
|
||||||
|
Node head = generateRandomNode(level, range);
|
||||||
|
boolean queue = ByQueue.isCBT1(head);
|
||||||
|
boolean recursion = Recursion.isCBT(head);
|
||||||
|
if (queue != recursion) {
|
||||||
|
System.out.println("fuck!!!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println("end");
|
||||||
|
|
||||||
|
}
|
||||||
|
static Node generateRandomNode(int n,int r){
|
||||||
|
return generateNode(1,n,r);
|
||||||
|
}
|
||||||
|
static Node generateNode(int i,int n,int r){
|
||||||
|
if (i > n || Math.random() < 0.5) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node head = new Node((int) (r * Math.random()));
|
||||||
|
head.left = generateNode(i + 1, n, r);
|
||||||
|
head.right = generateNode(i + 1, n, r);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ByQueue{
|
||||||
|
public static boolean isCBT(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Queue<Node> queue = new LinkedList<>();
|
||||||
|
queue.offer(head);
|
||||||
|
boolean leaf = false;
|
||||||
|
Node cur = null;
|
||||||
|
Node l = null;
|
||||||
|
Node r = null;
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
cur = queue.poll();
|
||||||
|
l = cur.left;
|
||||||
|
r = cur.right;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isCBT1(Node head){
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Queue<Node> queue = new LinkedList<>();
|
||||||
|
queue.offer(head);
|
||||||
|
Node cur;
|
||||||
|
Node l = null;
|
||||||
|
Node r = null;
|
||||||
|
boolean leaf = false;
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
cur = queue.poll();
|
||||||
|
l = cur.left;
|
||||||
|
r = cur.right;
|
||||||
|
if (l!= null) {
|
||||||
|
queue.offer(l);
|
||||||
|
}
|
||||||
|
if (r != null) {
|
||||||
|
queue.offer(r);
|
||||||
|
}
|
||||||
|
if ((leaf &&
|
||||||
|
(l != null || r != null))
|
||||||
|
|| (l == null && r != null)
|
||||||
|
) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (l == null || r == null) {
|
||||||
|
leaf = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Recursion{
|
||||||
|
public static boolean isCBT(Node head) {
|
||||||
|
return process(head).isCBT;
|
||||||
|
|
||||||
|
}
|
||||||
|
public static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return new Info(true, true, 0);
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
int height = Math.max(left.height, right.height) + 1;
|
||||||
|
boolean isFull = left.isFull && right.isFull && right.height == left.height;
|
||||||
|
boolean isCBT = false;
|
||||||
|
if (isFull) {
|
||||||
|
isCBT = true;
|
||||||
|
}else{
|
||||||
|
//如果左右都不是满二叉树的情况下
|
||||||
|
//左树是满二叉树并且右树是满二叉树
|
||||||
|
if (left.isCBT && right.isCBT) {
|
||||||
|
//左树是二叉树,右树是满二叉树,左树的高度比右树高度大1
|
||||||
|
if (left.isCBT && right.isFull && left.height == right.height + 1) {
|
||||||
|
isCBT = true;
|
||||||
|
}
|
||||||
|
//左树是满二叉树,右树是满二叉树,左树的高度比右树高度大1
|
||||||
|
if (left.isFull && right.isFull && left.height == right.height + 1) {
|
||||||
|
isCBT = true;
|
||||||
|
}
|
||||||
|
//左树是满二叉树,右树是二叉树,左树高度与右树高度一样
|
||||||
|
if (left.isFull && right.isCBT && right.height == left.height) {
|
||||||
|
isCBT = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Info(isFull, isCBT, height);
|
||||||
|
}
|
||||||
|
static class Info{
|
||||||
|
boolean isFull;
|
||||||
|
boolean isCBT;
|
||||||
|
int height;
|
||||||
|
public Info(boolean f,boolean c,int h){
|
||||||
|
this.isFull = f;
|
||||||
|
this.isCBT = c;
|
||||||
|
this.height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
package leo.class08_12;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName IsFull
|
||||||
|
* @DATE 2020/12/11 7:14 下午
|
||||||
|
* @Description 判断一颗二叉树是否是满二叉树
|
||||||
|
* 高度为h,节点为(2^h)-1个
|
||||||
|
*/
|
||||||
|
public class IsFull {
|
||||||
|
|
||||||
|
static class Code{
|
||||||
|
static boolean isFull(Node head){
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Info info = process(head);
|
||||||
|
return info.nodeCount == (1 << info.height) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return new Info(0, 0);
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
int height = Math.max(left.height, right.height) + 1;
|
||||||
|
int nodeCount = left.nodeCount + right.nodeCount + 1;
|
||||||
|
return new Info(height, nodeCount);
|
||||||
|
}
|
||||||
|
static class Info{
|
||||||
|
int height;
|
||||||
|
int nodeCount;
|
||||||
|
public Info(int h,int c){
|
||||||
|
this.height = h;
|
||||||
|
this.nodeCount = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Logarithm{
|
||||||
|
static boolean isFull(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int n = n(head);
|
||||||
|
int h = h(head);
|
||||||
|
return (1 << h) - 1 == n;
|
||||||
|
}
|
||||||
|
static int n(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return n(node.left) + n(node.right) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int h(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return Math.max(h(node.left), h(node.right)) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
int level = 5;
|
||||||
|
int range = 100;
|
||||||
|
int testTime = 1000000;
|
||||||
|
System.out.println("start!");
|
||||||
|
|
||||||
|
for (int i = 0; i < testTime; i++) {
|
||||||
|
Node head = generateRandomNode(level, range);
|
||||||
|
boolean c = Code.isFull(head);
|
||||||
|
boolean l = Logarithm.isFull(head);
|
||||||
|
if (c != l) {
|
||||||
|
System.out.println("fuck!!!!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("end!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node generateRandomNode(int n, int r){
|
||||||
|
return generate(1,n,r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node generate(int i, int n, int r) {
|
||||||
|
if (i > n || Math.random() < 0.5) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node head = new Node((int) (r * Math.random()));
|
||||||
|
head.left = generate((i + 1), n, r);
|
||||||
|
head.left = generate((i + 1), n, r);
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,196 @@
|
|||||||
|
package leo.class08_12;
|
||||||
|
|
||||||
|
import class08_12.Code08_MaxDistance;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName Max
|
||||||
|
* @DATE 2020/12/11 7:00 下午
|
||||||
|
* @Description 求二叉树的两个节点的最大距离
|
||||||
|
* 1.与顶级头结点有关
|
||||||
|
* 2.最大距离在左子树上
|
||||||
|
* 3.最大距离在右子树上
|
||||||
|
* 4.最大距离是左子树的高度与头结点的距离
|
||||||
|
* 5.最大距离是右子树的高度与头结点的距离
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MaxDistance {
|
||||||
|
|
||||||
|
static class Code{
|
||||||
|
public static int maxDistance(Node head) {
|
||||||
|
return process(head).maxDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Info process(Node node) {
|
||||||
|
if (node == null) {
|
||||||
|
return new Info(0, 0);
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
int maxDistance;
|
||||||
|
int height = Math.max(left.height, right.height) + 1;
|
||||||
|
int p1 = left.maxDistance;
|
||||||
|
int p2 = right.maxDistance;
|
||||||
|
int p3 = left.height + right.height + 1;
|
||||||
|
maxDistance = Math.max(Math.max(p1, p2), p3);
|
||||||
|
return new Info(maxDistance, height);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Info{
|
||||||
|
int maxDistance;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
public Info(int max, int h) {
|
||||||
|
this.maxDistance = max;
|
||||||
|
this.height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Code1{
|
||||||
|
public static int maxDistance(Node head){
|
||||||
|
return process(head).maxDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return new Info(0, 0);
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
int p1 = left.maxDistance;
|
||||||
|
int p2 = right.maxDistance;
|
||||||
|
int h = Math.max(right.height, left.height) + 1;
|
||||||
|
int p3 = right.height + left.height + 1;
|
||||||
|
int maxDistance = Math.max(Math.max(p1, p2), p3);
|
||||||
|
return new Info(maxDistance, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Info{
|
||||||
|
int height;
|
||||||
|
int maxDistance;
|
||||||
|
public Info(int max,int h){
|
||||||
|
this.maxDistance = max;
|
||||||
|
this.height = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class Logarithm{
|
||||||
|
public static int maxDistance1(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ArrayList<Node> arr = getPrelist(head);
|
||||||
|
HashMap<Node, Node> parentMap = getParentMap(head);
|
||||||
|
int max = 0;
|
||||||
|
for (int i = 0; i < arr.size(); i++) {
|
||||||
|
for (int j = i; j < arr.size(); j++) {
|
||||||
|
max = Math.max(max, distance(parentMap, arr.get(i), arr.get(j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList<Node> getPrelist(Node head) {
|
||||||
|
ArrayList<Node> arr = new ArrayList<>();
|
||||||
|
fillPrelist(head, arr);
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void fillPrelist(Node head, ArrayList<Node> arr) {
|
||||||
|
if (head == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
arr.add(head);
|
||||||
|
fillPrelist(head.left, arr);
|
||||||
|
fillPrelist(head.right, arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<Node, Node> getParentMap(Node head) {
|
||||||
|
HashMap<Node, Node> map = new HashMap<>();
|
||||||
|
map.put(head, null);
|
||||||
|
fillParentMap(head, map);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void fillParentMap(Node head, HashMap<Node, Node> parentMap) {
|
||||||
|
if (head.left != null) {
|
||||||
|
parentMap.put(head.left, head);
|
||||||
|
fillParentMap(head.left, parentMap);
|
||||||
|
}
|
||||||
|
if (head.right != null) {
|
||||||
|
parentMap.put(head.right, head);
|
||||||
|
fillParentMap(head.right, parentMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int distance(HashMap<Node, Node> parentMap, Node o1, Node o2) {
|
||||||
|
HashSet<Node> o1Set = new HashSet<>();
|
||||||
|
Node cur = o1;
|
||||||
|
o1Set.add(cur);
|
||||||
|
while (parentMap.get(cur) != null) {
|
||||||
|
cur = parentMap.get(cur);
|
||||||
|
o1Set.add(cur);
|
||||||
|
}
|
||||||
|
cur = o2;
|
||||||
|
while (!o1Set.contains(cur)) {
|
||||||
|
cur = parentMap.get(cur);
|
||||||
|
}
|
||||||
|
Node lowestAncestor = cur;
|
||||||
|
cur = o1;
|
||||||
|
int distance1 = 1;
|
||||||
|
while (cur != lowestAncestor) {
|
||||||
|
cur = parentMap.get(cur);
|
||||||
|
distance1++;
|
||||||
|
}
|
||||||
|
cur = o2;
|
||||||
|
int distance2 = 1;
|
||||||
|
while (cur != lowestAncestor) {
|
||||||
|
cur = parentMap.get(cur);
|
||||||
|
distance2++;
|
||||||
|
}
|
||||||
|
return distance1 + distance2 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static Node generateRandomBST(int maxLevel, int maxValue) {
|
||||||
|
return generate(1, maxLevel, maxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for test
|
||||||
|
public static Node generate(int level, int maxLevel, int maxValue) {
|
||||||
|
if (level > maxLevel || Math.random() < 0.5) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node head = new Node((int) (Math.random() * maxValue));
|
||||||
|
head.left = generate(level + 1, maxLevel, maxValue);
|
||||||
|
head.right = generate(level + 1, maxLevel, maxValue);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int maxLevel = 4;
|
||||||
|
int maxValue = 100;
|
||||||
|
int testTimes = 1000000;
|
||||||
|
for (int i = 0; i < testTimes; i++) {
|
||||||
|
Node head = generateRandomBST(maxLevel, maxValue);
|
||||||
|
if (Logarithm.maxDistance1(head) != Code1.maxDistance(head)) {
|
||||||
|
System.out.println("Oops!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("finish!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,210 @@
|
|||||||
|
package leo.class08_12;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName MaxSubBSTSize
|
||||||
|
* @DATE 2020/12/11 7:17 下午
|
||||||
|
* @Description 在二叉树中,返回满足搜索二叉树条件的最多的节点个数
|
||||||
|
* Binary Search Tree
|
||||||
|
* 1.Left subtree is search binary tree
|
||||||
|
* 2.right subtree is search binary tree
|
||||||
|
* 3.max value of left subtree less than the value of head
|
||||||
|
* 4.min value of right subtree greater than the value of head
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 1.顶级节点不做头
|
||||||
|
* 1.1 左树中最大搜索二叉树的节点个数
|
||||||
|
* 1.2 右树中最大搜索二叉树的节点个数
|
||||||
|
* 2.顶级节点做头
|
||||||
|
* 2.1 左树是BST
|
||||||
|
* 2.3 右树是BST
|
||||||
|
* 2.4 左size+右size+1
|
||||||
|
*/
|
||||||
|
public class MaxSubBSTSize {
|
||||||
|
|
||||||
|
static class Code{
|
||||||
|
public static int maxSubBSTSize(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return process(head).maxSubBSTCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
boolean isBST = false;
|
||||||
|
int maxSubBSTSize = 0;
|
||||||
|
int max = node.value;
|
||||||
|
int min = node.value;
|
||||||
|
if (left != null) {
|
||||||
|
max = Math.max(max, left.max);
|
||||||
|
min = Math.min(min, left.min);
|
||||||
|
maxSubBSTSize = left.maxSubBSTCount;
|
||||||
|
}
|
||||||
|
if (right != null) {
|
||||||
|
max = Math.max(max, right.max);
|
||||||
|
min = Math.min(min, right.min);
|
||||||
|
maxSubBSTSize = Math.max(maxSubBSTSize, right.maxSubBSTCount);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(left == null ? true : left.isAllBST)
|
||||||
|
&& (right == null ? true : right.isAllBST)
|
||||||
|
&& (left == null ? true : left.max < node.value)
|
||||||
|
&& (right == null ? true : right.min > node.value)
|
||||||
|
) {
|
||||||
|
isBST = true;
|
||||||
|
maxSubBSTSize = (left == null ? 0 : left.maxSubBSTCount)
|
||||||
|
+ (right == null ? 0 : right.maxSubBSTCount) + 1;
|
||||||
|
}
|
||||||
|
return new Info(isBST, maxSubBSTSize, max, min);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Info{
|
||||||
|
boolean isAllBST;
|
||||||
|
int maxSubBSTCount;
|
||||||
|
int max;
|
||||||
|
int min;
|
||||||
|
|
||||||
|
public Info(boolean isAllBST, int maxSubBSTCount, int max, int min) {
|
||||||
|
this.isAllBST = isAllBST;
|
||||||
|
this.maxSubBSTCount = maxSubBSTCount;
|
||||||
|
this.max = max;
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Code1{
|
||||||
|
public static int maxSubBSTSize(Node head) {
|
||||||
|
if (head == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return process(head).maxSubBSTSize;
|
||||||
|
}
|
||||||
|
static Info process(Node node){
|
||||||
|
if (node == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Info left = process(node.left);
|
||||||
|
Info right = process(node.right);
|
||||||
|
boolean isBST = false;
|
||||||
|
int max = node.value;
|
||||||
|
int min = node.value;
|
||||||
|
int maxSubBSTSize = 0;
|
||||||
|
if (left != null) {
|
||||||
|
max = Math.max(max, left.max);
|
||||||
|
min = Math.min(min, left.min);
|
||||||
|
maxSubBSTSize = left.maxSubBSTSize;
|
||||||
|
}
|
||||||
|
if (right != null) {
|
||||||
|
max = Math.max(max, right.max);
|
||||||
|
min = Math.min(min, right.min);
|
||||||
|
maxSubBSTSize = Math.max(maxSubBSTSize, right.maxSubBSTSize);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(left == null ? true : left.isBST) &&
|
||||||
|
(right==null ? true : right.isBST) &&
|
||||||
|
(left==null ? true : left.max < node.value)&&
|
||||||
|
(right==null? true : right.min > node.value)
|
||||||
|
){
|
||||||
|
isBST = true;
|
||||||
|
maxSubBSTSize = (left == null ? 0 : left.maxSubBSTSize) +
|
||||||
|
(right == null ? 0 : right.maxSubBSTSize) + 1;
|
||||||
|
}
|
||||||
|
return new Info(isBST, maxSubBSTSize, max, min);
|
||||||
|
|
||||||
|
}
|
||||||
|
static class Info{
|
||||||
|
boolean isBST;
|
||||||
|
int maxSubBSTSize;
|
||||||
|
int max;
|
||||||
|
int min;
|
||||||
|
public Info(boolean isBST, int maxSubBSTSize, int max, int min) {
|
||||||
|
this.isBST = isBST;
|
||||||
|
this.maxSubBSTSize = maxSubBSTSize;
|
||||||
|
this.max = max;
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static class Logarithm{
|
||||||
|
public static int maxSubBSTSize(Node head){
|
||||||
|
if (head == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int size = getMaxSize(head);
|
||||||
|
if (size != 0) {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
return Math.max(maxSubBSTSize(head.left), maxSubBSTSize(head.right));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getMaxSize(Node node) {
|
||||||
|
if (node == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
List<Node> list = new ArrayList<>();
|
||||||
|
in(node,list);
|
||||||
|
for (int i = 1; i < list.size(); i++) {
|
||||||
|
if (list.get(i).value <= list.get(i - 1).value) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void in(Node node, List<Node> list) {
|
||||||
|
|
||||||
|
if (node == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
in(node.left, list);
|
||||||
|
list.add(node);
|
||||||
|
in(node.right, list);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
int level = 4;
|
||||||
|
int range = 100;
|
||||||
|
int test = 100000;
|
||||||
|
System.out.println("Start");
|
||||||
|
for (int i = 0; i < test; i++) {
|
||||||
|
Node head = generateRandomNode(level, range);
|
||||||
|
int i1 = Code1.maxSubBSTSize(head);
|
||||||
|
int i2 = Logarithm.maxSubBSTSize(head);
|
||||||
|
if (i1 != i2) {
|
||||||
|
System.out.println("fuck!!!!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("End");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node generateRandomNode(int n, int r) {
|
||||||
|
return generateNode(1, n, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Node generateNode(int i, int n, int r) {
|
||||||
|
if (i > n || Math.random() < 0.5) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Node head = new Node((int) (r * Math.random()));
|
||||||
|
head.left = generateNode(i + 1, n, r);
|
||||||
|
head.right = generateNode(i + 1, n, r);
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package leo.class08_12;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Leo
|
||||||
|
* @ClassName Node
|
||||||
|
* @DATE 2020/12/11 3:31 下午
|
||||||
|
* @Description 二叉树
|
||||||
|
*/
|
||||||
|
public class Node {
|
||||||
|
int value;
|
||||||
|
Node left;
|
||||||
|
Node right;
|
||||||
|
protected Node(int v){
|
||||||
|
this.value = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue