队列实现二叉树宽度优先遍历
1.按层遍历
先压入头结点
弹出并打印
压入左右孩子
public void level(Node head){
if (head==null){
return null;}
Queue<Node> queue =new LinkedList<>();
queue.add(head);
while(!queue.isEmpty()){
Node cur=queue.poll();
System.out.println(cur.value);
if(cur.left != null){
queue.add(cur.right)
}
if(cur.left != null){
queue.add(cur.right)
}
}
2.寻找最大宽度
用哈希表存储,key代表节点,value代表层数
哈希表存入下一个孩子节点时,层数加一
当前层遍历完成时,统计node数量
public void MaxWidth(Node head){
if (head==null){
return null;
}
Queue<Node> queue =new LinkedList<>();
queue.add(head);
HashMap<Node,Integer> levelMap=new HashMap<>();
leveMap.put(head,1);
int curLevel=1;
int curLevelNodes=0;
int max=0;
while(!queue.isEmpty()){
Node cur=queue.poll();
int curNodeLevel=LevelMap.get(cur);
if(cur.left != null){
levelMap.put(cur.left,curNodeLevel+1);
queue.add(cur.right)
}
if(cur.left != null){
levelMap.put(cur.right,curNodeLevel+1);
queue.add(cur.right)
}
if(curNodeLevel==curLevel){
curLevelNodes++;
}
else{
max=Math.max(max,curLevelNodes);
curLevel++;
curLevelNodes=1;
}
}
max=Math.max(max,curLevelNodes);
return max;
}
折纸问题
把纸对折一次会出现凹的一道折痕,再折一次会出现凹凹凸的三道折痕
凹折痕出现在老折痕的上方,凸折痕出现在老折痕的下方
输出折痕即为输出中序遍历
从第一层开始往下,先打印左边的凹,在打印右边的凸,如果当前层数大于对折次数就直接返回
import java.util.Scanner;
public class Main {
public static void printAllfolds(int n){
printProcess(1, n ,true);
}
public static void printProcess(int i,int n,boolean down){
if (i>n){
return;
}
printProcess(i+1,n,true);
System.out.println(down ?"凹":"凸");
printProcess(i + 1, n, false);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
printAllfolds(n);
}
}
判读一个树是不是平衡二叉树
假设所有信息都可以得到,判断左子树和右子树是否平衡,高度差不大于1
头结点为X
public static class Info{
public boolean isBalaced;
public int height;
public Info(boolean b,int h){
isBalaced=b;
height=h;
}
}
public static Info process(Node X){
if(X==null)
return new Info (true,0);
Info leftInfo=process(X.left);
Info rightInfo=proccess(X.right);
//左右最高的加上头结点
int height=Math.max(leftInfo.height,rightInfo.height)+1;
boolean isBalanced=true;
if(!leftInfo.isBalanced||!rightInfo.isBalanced||Math.abs(leftInfo.height-rightInfo.height)>1)
isBalanced=false;
return new Info(isBalanced,height);
}
求二叉树中最大距离
两种情况
1.通过头结点
最大距离为左树最大高度+1+右树最大高度
2.不通过头结点
最大距离为max(左树最大距离,右树最大距离)
public static class Info{
public int maxDistance;
public int height;
public Info(int m,int h){
maxDistance=m;
height=h;
}
}
public static Info process(Node X){
if(X=null)
return new Info (0,0);
Info leftInfo=process(X.left);
Info rightInfo=process(X.right);
int height=Math.max(leftInfo.height,rightInfo.height)+1;
int maxDistance=Math.max(
Math.max(leftInfo.maxDistance,rightInfo.maxDistance),
leftInfo.height+1+rightInfo.height
);
return new Info(maxDistance,height);
}
找出最大的二叉树搜索子树
两种情况
1.与X无关,最大子树在左子或树右子树中
2.与X有关,以X为头,左子树为搜索二叉树,右子树为搜索二叉树,
左max<X,右min>X
public static class Info{
public int max;
public int min;
public boolean isAllBST;
public int maxSubBSTSize;
public Info(boolean is,int size,int m,int n){
isAllBST=is;
maxSubBSTSize=size;
max=m;
min=n;
}
}
public static Info process(Node X){
if(X==null){
return null;
}
Info leftInfo=process(X.left);
Info rightInfo=process(X.right);
int min=X.value;
int max=X.value;
if(leftInfo!=null){
min=Math.min(min,leftInfo.min);
max=Math.max(max,leftInfo.max);
}
if(rightInfo!=null){
min=Math.min(min,rightInfo.min);
max=Math.max(max,rightInfo.max);
}
int maxSubBSTSize =0;
if(leftInfo!=null){
maxSubBSTsize=leftInfo.maxSubBSTSize;
}
if(rightInfo!=null){
maxSubBSTsize=Math.max(maxSubBSTSize,rightInfo.maxSubBSTSize);
}
boolean isAllBST =false;
if((leftInfo==null?true:leftInfo.isAllBST)
&&
(rightInfo==null?true:rightInfo.isAllBST)
&&
(leftInfo==null?true:leftInfo.max<X.value)
&&
(rightInfo==null?true:rightInfo.min>X.value)
){
maxSubBSTSize=((leftInfo==null?0:leftInfo.maxSubBSTSize)
+(rightInfo==null?0:rightInfo.maxSubBSTSizze));
isAllBST==true;
}
return new Info(isAllBST,maxSubBSTSize,max,min);
}