队列实现二叉树宽度优先遍历

队列实现二叉树宽度优先遍历

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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值