《剑指offer》– 从上往下打印二叉树、二叉搜素树的后序遍历、二叉树中和为某一值的路径、二叉树与双向链表

《剑指offer》– 从上往下打印二叉树、二叉搜素树的后序遍历、二叉树中和为某一值的路径、二叉树与双向链表

一、从上往下打印二叉树:

1、题目:

上往下打印出二叉树的每个节点,同层节点从左至右打印。

2、解题思路:

用arraylist模拟一个队列来存储相应的TreeNode。

3、代码实现:

public class Test9 {

	 public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
		 
		 ArrayList<Integer> list=new ArrayList<Integer>();
		 if(root == null){
			 return list;
		 }
		 
		 ArrayList<TreeNode> queen=new ArrayList<TreeNode>();
		 queen.add(root);
		 while(queen.size()!=0){
			 TreeNode temp=queen.remove(0);
			 
			 if(temp.left!=null){
				 queen.add(temp.left);
			 }
			 if(temp.right!=null){
				 queen.add(temp.right);
			 }
			 
			 list.add(temp.val);
		 }
		 return list;
	 }
}

class TreeNode{
	int val = 0;
    TreeNode left = null;
    TreeNode right = null;

	public TreeNode(int val) {
        this.val = val;
    }
}

二、二叉搜索树的后序遍历:

1、题目:

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同

2、解题思路:

已知条件:后序序列最后一个值为root;二叉搜索树左子树值都比root小,右子树值都比root大。
(1)确定root;
(2)遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树;
(3)遍历右子树,若发现有小于root的值,则直接返回false;
(4)分别判断左子树和右子树是否仍是二叉搜索树(即递归步骤1、2、3)。

3、代码实现:

public class Test10 {

	public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length==0){
        	return false;
        }
        if(sequence.length==1){
        	return true;
        }
		
		return judge(sequence,0,sequence.length-1);
    }
	
	public boolean judge(int [] sequence,int startIndex,int rootIndex){
		
		if(startIndex>rootIndex){
			return true;
		}
		int i=startIndex;
		//找到右子树的第一个节点的下标
		while(sequence[i]<sequence[rootIndex]){
			i++;
		}
		
		for(int j=i;j<rootIndex;j++){
			if(sequence[j]<sequence[rootIndex]){
				return false;
			}
		}
		return judge(sequence,startIndex,i-1)&&judge(sequence,i,rootIndex-1);
	}
}

三、二叉树中和为某一值的路径:

1、题目

输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)。

2、解题思路:

 (1)root入栈,跳入该子树进行寻路操作 ;
 (2)若root的这条路径,已满足要求,则将该路径加入到listAll中去;
 (3)对root左右子树,继续寻路;
 (4)root出栈,该子树访问完毕;

3、代码实现:

public class Test11 {

	private ArrayList<ArrayList<Integer>> resultList=new ArrayList<>();//最终返回的resultList
	private ArrayList<Integer> list= new ArrayList<>();
	
	 public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {

		 find(root,target);
		 
		 //对resultList的进行按长度排序
		 Collections.sort(resultList,new Comparator<ArrayList<Integer>>() {
			@Override
			public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
				return o2.size()-o1.size();
			}
		 });
		 
		 return resultList;
	 }
	 
	 public void find(TreeNode root,int target){
		 if(root==null){
			 return ;
		 }
		 list.add(root.val);
		 target=target-root.val;
		 
		 if(target==0 && root.left==null && root.right==null){
			 resultList.add(new ArrayList<Integer>(list));
		 }
		 
		 //如果提前超过target的值,则终止遍历,不继续查找子节点
		 if(target<0){
			 list.remove(list.size()-1);
			 return ;
		 }
		 
		 find(root.left,target);
		 find(root.right,target);
		 
		 //回退
		 list.remove(list.size()-1);
	 }
}

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }
}

四、二叉树与双向链表:

1、题目:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

2、解题思路:

代码中有注释。

3、代码实现:

public class Test13 {
	
	//第二种递归方式:
	//改进步骤2:
	//记录子树链表的最后一个节点,终结点只可能为只含左子树的非叶节点与叶节点
	protected TreeNode leftLast = null;
	public TreeNode Convert2(TreeNode pRootOfTree) {
		if(pRootOfTree == null){
    		return null;
    	}
    	if(pRootOfTree.left == null && pRootOfTree.right == null){
    		leftLast = pRootOfTree;
    		return pRootOfTree;
    	}
    	
    	//1、将左子树构造成双链表,并返回链表头结点。
    	TreeNode left=Convert2(pRootOfTree.left);
    	
    	//3、如果左子树的链表不为空的话,将当前root追加到左子树链表
    	if(left!=null){
    		leftLast.right = pRootOfTree;
    		pRootOfTree.left=leftLast;
    	}
    	
    	leftLast = pRootOfTree;//当根节点只含左子树时,则该根节点为最后一个节点。
    	
    	//4、将右子树构造成双链表,并返回链表头结点
    	TreeNode right= Convert2(pRootOfTree.right);
    	
    	//5、如果右子树链表不为空的话,将该链表追加到root节点
    	if(right!=null){
    		right.left=pRootOfTree;
    		pRootOfTree.right=right;
    	}
    	return left!=null?left:pRootOfTree;
	}
	
	
	//第一种递归方式:
	public TreeNode Convert(TreeNode pRootOfTree) {
    	if(pRootOfTree == null){
    		return null;
    	}
    	if(pRootOfTree.left == null && pRootOfTree.right == null){
    		return pRootOfTree;
    	}
    	
    	//1、将左子树构造成双链表,并返回链表头结点。
    	TreeNode left=Convert(pRootOfTree.left);
    	TreeNode p=left;
    	
    	//2、定位至左子树双链表最后一个节点
    	while(p!=null && p.right!=null){
    		p=p.right;
    	}
    	
    	//3、如果左子树的链表不为空的话,将当前root追加到左子树链表
    	if(left!=null){
    		p.right = pRootOfTree;
    		pRootOfTree.left=p;
    	}
    	
    	//4、将右子树构造成双链表,并返回链表头结点
    	TreeNode right= Convert(pRootOfTree.right);
    	
    	//5、如果右子树链表不为空的话,将该链表追加到root节点
    	if(right!=null){
    		right.left=pRootOfTree;
    		pRootOfTree.right=right;
    	}
    	
    	return left!=null?left:pRootOfTree;
    }
}

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114695.html原文链接:https://javaforall.net

(0)
上一篇 2021年10月3日 下午7:00
下一篇 2021年10月3日 下午7:00


相关推荐

  • ubuntu20.04主题美化_ubuntu优化工具

    ubuntu20.04主题美化_ubuntu优化工具用了这么长时间ubuntu了,也该让自己的老婆漂亮点了。对吧。 于是搜之,找到资料记录一下: 资料链接:http://www.ubuntuhome.com/ubuntu-10-04-install-themes.html 主要步骤:添加ppa源,然后下载好看的主题,具体见资料链接。 记录一下添加源:首先打开终端并依次输入:sudoadd-apt-r…

    2026年2月26日
    3
  • kali安装步骤

    kali安装步骤kali镜像下载地址:http://mirrors.ustc.edu.cn/kali-images/1.    新建虚拟机 -选择自定义选择虚拟机硬件兼容性(默认我的是12.0)选择下一步选择稍后安装操作系统-下一步选择linux内核3.x 64位-下一步修改虚拟机名称为kali2.0   路径为我自己在G创建的kali文件夹处理器 1核我本机物理内存不大够了所以设置512M-…

    2022年5月6日
    63
  • uva 11151 Longest Palindrome (最长公共子序列)[通俗易懂]

    uva 11151 Longest Palindrome (最长公共子序列)[通俗易懂]uva11151LongestPalindromeApalindromeisastringthatreadsthesamefromtheleftasitdoesfromtheright.Forexample,I,GAGandMADAMarepalindromes,butADAMisnot.Here,weconsideralso

    2022年7月11日
    22
  • 串口调试助手fx2n_PLC串口调试助手详细讲解(结合实操)「建议收藏」

    串口调试助手fx2n_PLC串口调试助手详细讲解(结合实操)「建议收藏」下面技成培训网给大家分享一则案例文,学员常见问题!经常会有学员问,老师老师,我的PLC和变频器通讯不上了,不知道什么原因,您能帮我看看么。其实吧,这个一般远程是帮不上你什么的,还是要你自己去测试,找出问题,那么怎么测试呢,今天就给大家做一个详细的解说,我们通过一个实际对的案例,结合一个叫做串口调试助手的小工具,带大家了解,通讯出问题了,一般是怎么去查找问题的。案例是这样的:一台三菱的PLC,PLC…

    2022年6月4日
    59
  • dtu连接mysql_Azure SQL 数据库中的DTU和eDTU是什么

    dtu连接mysql_Azure SQL 数据库中的DTU和eDTU是什么AzureSQL数据库中的DTU和eDTU是什么03/07/20177分钟可看完本文内容MaxShen沈云技术解决方案专家AzureSQL使用了数据库事务单位(DTU)和弹性数据库事务单位(eDTU)来作为一个计量单位。但是DTU和eDTU究竟是什么?在官方文档中是这样解释的:DTU是一个资源度量单位,表示保证可用于单一数据库服务层内特定性能级别的单个AzureSQL…

    2025年6月13日
    4
  • iptable配置[通俗易懂]

    iptable配置[通俗易懂]简介:iptables是与最新的2.4.x版本Linux内核集成的IP信息包过滤系统。如果Linux系统连接到因特网或LAN、服务器或连接LAN和因特网的代理服务器,则该系统有利于在Linux系统上更好地控制IP信息包过滤和防火墙配置。—来自百度百科配置使用说明:1.封IP1>.单个IP的命令是iptables-IINPUT-s

    2022年5月8日
    62

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号