《剑指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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SAP_FICO常用BAPI

    SAP_FICO常用BAPI1、检查创建凭证所需数据是否正确BAPI_ACC_DOCUMENT_CHECK;   2、创建凭证BAPI_ACC_DOCUMENT_POST。

    2022年7月24日
  • 今天发现一个好用的查询IP地址的工具,记录一波「建议收藏」

    今天发现一个好用的查询IP地址的工具,记录一波

    2022年2月15日
  • Collections的 sort方法

    Collections的 sort方法Collections的sort方法可以对List类型的集合进行排序,具体如下:

    2022年7月2日
  • 开车旅行游戏_开车周游世界

    开车旅行游戏_开车周游世界题目链接这道题最基本的思路是用倍增,但是其实它的难点在预处理部分。倍增的部分此次就不细说了,和之前的最近公共祖先的思想类似。我们主要来探讨一下预处理的部分。我们需要预处理出每个城市小A和小B的选择目标和对应的距离,接下来就可以处理出进行2k轮开车的目的地和距离了。所以前者才是重中之重,而前者如果要用暴力的方法会tle的。有人可能会疑惑,我们找当前点的后面两三个不就可以了?为什么会tle呢?实际上并不是序号相差很远距离就很远,实际上有可能第一个城市和最后一个城市最近,可以举个例子,城市海拔如下:

    2022年8月22日
  • 基于51单片机八路抢答器课程设计(含proteus仿真图及代码)

    基于51单片机八路抢答器课程设计(含proteus仿真图及代码)一、设计要求:1、可满足8个选手的抢答2、具有主持者控制开关,用来控制系统清零和抢答开始3、抢答器具有数据锁存功能、显示功能和声音提示功能4、抢答开始后,若有选手按动抢答器按钮,编号立即锁存,并在LED数5、码管上显示选手的编号,同时灯亮且伴随声音提示,还要禁止其后的抢答输入二、实验设计和分析1 总体设计方案方案一:采用数字电路控制。采用数字显示电路的好处就是设计简单。用以在P0口…

    2022年10月20日
  • Linux文件系统详解

    从操作系统的角度详解Linux文件系统层次、文件系统分类、文件系统的存储结构、不同存储介质的区别(RAM、ROM、Flash)、存储节点inode。本文参考:http://blog.chinaunix.net/uid-8698570-id-1763151.htmlhttp://www.iteye.com/topic/816268http://soft.chinabyte.com/os/142…

    2022年4月3日

发表回复

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

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