精华内容
下载资源
问答
  • 二叉树根节点到叶子节点路径问题

    千次阅读 2020-05-19 16:53:16
    关于二叉树根节点到叶子节点路径问题,最容易想到的就是打印二叉树所有根节点到叶子节点的路径。这个很容易,就是以二叉树的前序遍历为基础,在遍历过程中记录遍历的节点然后碰到叶子节点就输出结果。代码如下: ...

    前言

    最近在刷leetcode的关于二叉树的题目,碰到几题关于二叉树节点的问题。在这里做一个小结记录自己的理解和知识的长进。
    

    leetcode问题

    1. 路径总和
    2. 路径总和Ⅱ

    思路总结

    前序

    关于二叉树根节点到叶子节点路径问题,最容易想到的就是打印二叉树所有根节点到叶子节点的路径。这个很容易,就是以二叉树的前序遍历为基础,在遍历过程中记录遍历的节点然后碰到叶子节点就输出结果。代码如下:
    
     public static void printAllPath(TreeNode root,String s) {
            if(root==null){
                return;
            }
            s += root.val+ " ";
            if(root.left==null&&root.right==null) {
                System.out.println(s.trim().replaceAll(" ","->"));
            }
            printAllPath(root.left,s);
            printAllPath(root.right,s);
        }
    

    问题一

    那么仿照前序中提到的打印问题,我们只需要在递归过程中记录路径的之和,最后在叶子节点处做一次判断即可。代码如下:
    

    路径总和问题

    class Solution {
       public boolean hasPathSum(TreeNode root, int sum) {
         return hasPath(root, 0, sum);
        }
        private boolean hasPath(TreeNode root, int curSum, int sum){
            if (root == null)
                return false;
            curSum += root.val;
            if (root.left == null && root.right == null){
                if (curSum == sum)
                    return true;
            }
            if (hasPath(root.left, curSum, sum))
                return true;
            return hasPath(root.right, curSum, sum);
        }
    }
    

    说明

    递归终止条件:节点为空时
    递归内容:记录到达当前节点路径之和为curSum,判断当前节点是否为叶子节点,如果是则判断路径之后是否跟目标值相等,相等则返回true。
    递归入口:当前节点判断完成之后,就要分别递归调用左子树和右子树,一旦找到路径则返回true即可。
    

    问题二

    问题二是对问题一的升级,要把符合条件的路径记录下来。我当时坐这个题的第一反应就是,继续仿照路径打印的思路,只不过将函数的形参String改成列表,然后遍历时将路径节点添加到列表中就好了,最后再对所有路径筛选,选出和为目标值的即可。这是我第一次写的代码:

      private void allPath(TreeNode root, List<List<Integer>> result, List<Integer> list){
            if (root == null)
                return ;
            list.add(root.val);
            if (root.left == null && root.right == null){
                result.add(list);
            }
            if (root.left != null)
                allPath(root.left, result, list);
            if (root.right != null)
                allPath(root.right, result, list);
        }
    

    这个方法写完之后我还很高兴,我觉得我把问题解决了。可是自己用几个用例测试以后根本不行,后来我突然明白了List作为函数形参与String作为函数形参有很大的不同。
    List作为形参时方法可以改变它的内容,在递归调用中任意一层的递归函数对其改变都将影响其他所有递归函数中list的值。而String作为函数形参时每次都会产生一个对象副本,函数只修改形参中的String的值。关于Java函数形参问题是个老生常谈的问题,看来我还没有做到写方法时候很好的掌握其中的区别。
    接着我对这个方法进行了修改,尝试着在递归过程中对list进行回溯,这是第二个版本:

      private static void allPath(TreeNode root, List<List<Integer>> result, List<Integer> list){
            if (root == null)
                return ;
            list.add(root.val);
            if (root.left == null && root.right == null){
                result.add(list);
                list.remove(list.size() - 1);
            }
            if (root.left != null)
                allPath(root.left, result, list);
            if (root.right != null)
                allPath(root.right, result, list);
        }
    

    结果依然不对。后来在leetcode本题的题解中看到了正确的回溯办法,链接:113.java 回溯详解 打败99.98%。根据这个作者的思想,对第二版代码进行了修改:

      private static void allPath(TreeNode root, List<List<Integer>> result, List<Integer> list){
            if (root == null)
                return ;
            list.add(root.val);
            if (root.left == null && root.right == null){
                result.add(new ArrayList<>(list));
                list.remove(list.size() - 1);
                return;
            }
            if (root.left != null)
                allPath(root.left, result, list);
            if (root.right != null)
                allPath(root.right, result, list);
            list.remove(list.size() - 1);//这一步回溯非常关键,目前还不太能理解
        }
    

    最终代码:

     private  void backTargetPath(TreeNode root, List<List<Integer>> result, List<Integer> list, int curSum, int sum){
            if (root == null)
                return;
            curSum += root.val;
            list.add(root.val);
            if (root.left == null && root.right == null){
                if (curSum == sum)
                    result.add(new ArrayList<>(list));
                list.remove(list.size() - 1);
                return;
            }
            if (root.left != null)
                backTargetPath(root.left, result, list, curSum, sum);
            if (root.right != null)
                backTargetPath(root.right, result, list, curSum, sum);
            list.remove(list.size() - 1);
        }
    
    展开全文
  • 二叉树根节点到叶子节点的所有路径和 题目描述 给定一个仅包含数字 0−9\ 0-9 0−9 的二叉树,每一条从根节点到叶子节点的路径都可以用一个数字表示。 例如根节点到叶子节点的一条路径是1→2→31\to 2\to 31→2→3,...

    二叉树根节点到叶子节点的所有路径和

    题目描述

    给定一个仅包含数字 0−9\ 0-9 0−9 的二叉树,每一条从根节点到叶子节点的路径都可以用一个数字表示。
    例如根节点到叶子节点的一条路径是1→2→31\to 2\to 31→2→3,那么这条路径就用 123\ 123 123 来代替。
    找出根节点到叶子节点的所有路径表示的数字之和
    例如:
    在这里插入图片描述
    这颗二叉树一共有两条路径,
    根节点到叶子节点的路径 1→21\to 21→2 用数字 12\ 12 12 代替
    根节点到叶子节点的路径 1→31\to 31→3 用数字 13\ 13 13 代替
    所以答案为 12+13=25\ 12+13=25 12+13=25

    代码

    import java.util.*;
    
    /*
     * public class TreeNode {
     *   int val = 0;
     *   TreeNode left = null;
     *   TreeNode right = null;
     * }
     */
    
    public class Solution {
        /**
         * 
         * @param root TreeNode类 
         * @return int整型
         */
        public int sumNumbers (TreeNode root) {
            // write code here
            if(root == null) return 0;
            //当只有一个root时,返回0,不通过;
            //return method(root.left, root.val) + method(root.right, root.val);
            return method(root, 0);
        }
        
        public int method(TreeNode root, int v){
            if(root == null){
                return 0;
            }
            //当子root都为空时,直接返回
            if(root.left==null && root.right==null){
                return v*10 + root.val;
            }
            //都不为空,都往下探索
            //一个为空,返回为0,另一个继续往下探索
            return  method(root.left, v*10 + root.val) + method(root.right, v*10 + root.val);
        }
    }
    
    展开全文
  • 二叉树——根节点到特定节点路径查找一、思路二、代码实现 一、思路 使用二叉链表创建的二叉树,这里我的思路是用链栈来存放找寻二叉树特定节点中,用来存放节点元素 个人思路:创建链栈,遍历二叉树并把路径中...

    二叉树——根节点到特定节点路径查找

    一、思路

    使用二叉链表创建的二叉树,这里我的思路是用链栈来存放找寻二叉树特定节点中,用来存放节点元素

    个人思路:创建链栈,遍历二叉树并把路径中节点元素存放到栈中(如下图所示):

    L 为一开始创建的链栈头指针
    flag = 1,作为标记符,表示还没在一条路径中,找到要找的特定节点元素

    在这里插入图片描述

    二、代码实现

    思路理解不了,可以结合运行结果图,加上自己画图理解,运行结果在最下方

    #include<stdio.h>
    #include<stdlib.h>
    
    //	二叉树结构体 
    typedef struct TreeLink{
    	int Data;
    	struct TreeLink *LChild;	//	左子树指针
    	struct TreeLink *RChild;	//	右子树指针
    }T_LINK,*TLINK;	
    
    //	链栈 
    typedef struct STACK{
    	
    	int data;
    	struct STACK *next;	
    	
    }StackNode,*Stack; 
    
    int flag;	//	标记符 
    Stack L;	//	链栈头节点指针 
    
    //************************* 二叉树 ***********************// 
    //	创建二叉树 
    TLINK Create_TreeLink()
    {
    	TLINK T;
    	
    	int data;
    	int temp;
    	 
    	scanf("%d",&data);
    	temp = getchar();	//	吸收scanf带来的回车 
    
    	if(data == -1){		//	输入-1表示该节点下左树或者右树下不存数据,返回到上一级节点 
    		
    		return NULL;		
    	
    	}else{
    		
    		T = (TLINK)malloc(sizeof(T_LINK));	//	每个节点开辟空间 
    	
    		T->Data = data;
    		
    		printf("请输入%d节点下左节点数据:  ",data);
    		T->LChild = Create_TreeLink();
    		
    		printf("请输入%d节点下右节点数据:  ",data);
    		T->RChild = Create_TreeLink();
    		
    		return T;
    	}
    	
    }
    //	先序遍历二叉树
    void ShowXianXu(TLINK S)
    {
    	if(S==NULL){
    		
    		return;
    	}	
    	printf("%d ",S->Data);
    	ShowXianXu(S->LChild);
    	ShowXianXu(S->RChild);
    } 
    
    //************************* 链 栈 *********************//
    
    //	入栈
    void PushStack(int x)
    {
    	Stack top;
    	top = (Stack)malloc(sizeof(StackNode));
    	top->data = x;
    	top->next = L;		//	第一次是让一开始的头节点存入元素,尾巴指向NULL已经初始化好
    	L = top;			//	之后便是创建新的链栈节点和之前的串起来
    } 
    
    //	出栈
    int PopStack()
    {
    	int x;
    	
    	if(L->next==NULL)	//	栈空
    	{
    		printf("出栈完毕\n");
    		exit(-1);
    	}else{
    		
    		Stack p;
    		x = L->data;
    		p = L;			//	让原来的L变成P 
    		L = p->next;	//	原来头节点next指向的变成新的头节点 
    		free(p);		//	释放原来的头节点 
    		return x;		//	返回原来头节点里头的元素 
    		
    	}
    	
    } 
    
    //	进入二叉树搜索特定节点
    void CherkNode(TLINK T,int data)
    {
    	if(T==NULL)
    	{
    		return;
    	}	
    	
    	if(flag==1)		//	标记符flag 还是1时,表示还没找到要找的节点 
    	{
    		printf("入栈元素为: %d\n",T->Data);
    		PushStack(T->Data); 	//	入栈
    	}
    	if(T->Data == data)		//	已经在二叉树中遍历到要找的节点元素 
    	{
    		printf("元素找到,元素为: %d\n",T->Data);
    		flag = 0;
    		return; 
    	}
    	
    	CherkNode(T->LChild,data);	//	遍历这个节点左子树,为NULL时才结束递归,返回上一级节点
    	CherkNode(T->RChild,data);	//	遍历这个节点的右子树,为NULL时返回上一级节点
    	
    	if(flag==1)		//	递归遍历二叉树每条路径中寻找,由于遍历一个节点 
    	{				//	就会让元素入栈,以便将后面元素不是要找路径之中的元素,从栈中清除 
    		printf("出栈元素: %d\n",T->Data); 
    		PopStack();	//	清除非要寻找路径上的栈中元素	
    	}
    	
    	
    } 
    //	搜索路径 
    void SearchPath(TLINK T,int data)
    {
    	int temp[30];	//	用来存最后找到的路径各个节点里头的数据 
    	int i;
    	flag = 1;		//	标记符 
    	
    	L = (Stack)malloc(sizeof(StackNode));	//	分配空间给指针 
    	L->next = NULL;		//	让第一个节点指针指向NULL,最后也就是栈底指针 
    	
    	if(T==NULL)		//	空树 
    	{
    		return;
    	}
    	
    	CherkNode(T,data);	//	搜索二叉树中要找的节点,进行入栈出栈操作 
    	
    	for(i=0;L->next;i++)
    	{
    		temp[i] = PopStack();	//	找到的路径元素逆序存放在数组temp[]中 
    	} 
    	printf("路径寻找成功,路径如下:\n");
    	for(i--;i>=0;i--)
    	{
    		printf("%d ",temp[i]);
    	}
    }
    
    //	主函数 
    int main()
    {
    	
    	TLINK T;				//	创建二叉树指针  
    	int Node;
    	
    	printf("请输入第一个节点(输入-1表示该节点下无其他节点)\n");
    	T = Create_TreeLink();
    	printf("先序遍历如下:\n"); 
    	ShowXianXu(T); 
    	putchar('\n');
    	
    	printf("请输入你要找的特定节点:\n");
    	scanf("%d",&Node);
    	SearchPath(T,Node);		//	开始搜索节点
    	
    	return 0;
    }
    

    运行结果:

    在这里插入图片描述

    展开全文
  • 二叉树根节点到指定节点的路径这个算法是很多算法的基础。 比如说: 找节点的最近公共祖先,节点最大距离等都会用到此算法,所以要好好理解一下。

    二叉树根节点到指定节点的路径这个算法是很多算法的基础。
    比如说:
    找节点的最近公共祖先,节点最大距离等都会用到此算法,所以要好好理解一下。

    展开全文
  • 二叉树根节点到指定节点的路径

    万次阅读 2014-04-15 14:54:37
    题目描述:给定一棵二叉树二叉树中一个节点,输出根节点到指定节点间的路径。  10   / \   5 12   / \   4 7 指定节点7,那么输出路径应该是10-5-7。 分析与解法: 这个题目是在我...
  • 二叉树采用二叉链表存储结构进行存储,需要输出从二叉树的树根到指定结点的完整路径。按照给出的先序序列根据教材中算法6.4所示的算法建立二叉链表。二叉树中每个结点的数据都不相同。 Input 包含多组测试数据...
  • 题目描述:给定一棵二叉树二叉树中一个节点,输出根节点到指定节点间的路径。  10   / \   5 12   / \   4 7 指定节点7,那么输出路径应该是10-5-7。 分析与解法: 这个...
  • package tree; import java.util.LinkedList;... * 打印二叉树根节点到叶子节点的所有路径 * @param args */ public static void getPath(TreeNode root){ if(root==null) return; LinkedLis
  • 二叉树祖先节点_二叉树的祖先

    千次阅读 2020-07-29 06:08:02
    二叉树祖先节点Problem statement: 问题陈述: Given a Binary Tree and a target key, write a function that prints all the ancestors of the key in the given binary tree. 给定二叉树和目标键,编写一个...
  • 二叉树根节点到任意结点的路径)

    千次阅读 热门讨论 2020-04-28 21:22:42
    假设二叉树采用二叉链表方式存储, root指向结点,node 指向二叉树中的一个结点,编写函数 path,计算root到 node 之间的路径,(该路径包括root结点和 node 结点)。path 函数声明如下: bool path(BiTNode* root...
  • 二叉树节点

    千次阅读 2018-09-04 18:44:04
    1、前序:结点第一个访问,然后访问左、右孩子; 后序:结点最后访问,开始先...2、二叉树节点计算公式 N = n0+n1+n2,度为0的叶子节点比度为2的节点数多一个。N=1*n1+2*n2+1 3、具有n个节点的完全二叉树的深...
  • 输出二叉树叶子节点数目

    千次阅读 2016-09-15 22:34:16
    输出二叉树叶子节点数目,用递归实现方式,如果二叉树是一个空树,则输出0,如果二叉树...根节点入队,在while循环的时候,先出队,然后用当前节点指向出队队头节点 如果存在左孩子节点,则左孩子入队 如果存在右孩子
  • //查找二叉树指定节点 bool hasNode(TreeNode* pRoot, TreeNode* pNode){ if(pRoot == pNode) return true; bool has = false; if(pRoot-&gt;lchild != NULL) has = hasNode(pRoot-&gt;lchild, p...
  • 输入一颗二叉树根节点,判断该树是不是平衡二叉树 1. 解法一  该解法的思路:在遍历树的每个节点的时候,调用函数TreeDepth得到它的左右子树的深度。如果每个节点的左右子树的深度相差都不超过1,按照定义...
  • 问题这个题我在做一个测试的时候做的,当时我忘记保存题目了,只是记着题目大意:求二叉树根节点到每个叶子节点路径上不重复数字的最大个数。举个例子,如下二叉树:从根节点到叶子节点的路径总过有三条:(1,3,4,...
  • 1、题目 2、思路 class Solution { public: int TreeDepth(TreeNode* pRoot) { if(pRoot == nullptr) return 0; int left = TreeDepth(pRoot-&gt;left); int right...
  • 二叉树根结点到叶节点的最短距离

    千次阅读 2018-11-08 00:41:13
    最小深度是沿着从根节点到最近叶节点的最短路径的节点数目。 思路一:递归。 当节点左右子树都为null时,返回0 当左子树为null,返回右子树递归+1; 当右字数为null,返回左子树递归+1; 当左右子树都不为空,返回...
  • 思路:当用前序遍历的方式访问到某一个节点的时候,我们把该节点添加...因此我们在函数退出之前要在路径上删除当前节点,以确保返回父节点时路径刚好是从根节点到父节点的路径。 下面是寻找某一特定叶子节点的代码:
  • Sum Root to Leaf Numbers原题链接Sum Root to Leaf Numbers二叉树每个从根节点到叶子节点的路径都代表一个整数,计算所有整数的和只需要遍历一遍整棵数即可,需要注意必须是到达叶子节点代码如下/** * Definition ...
  • 根节点 到叶子节点组成一个数 前序遍历 每层的值都为上一层*10+本层结点的值 int sumNumbers(TreeNode *root) { int sum=0; if(root==NULL) return sum; return PreOrder(root,sum); } int PreO
  • 二叉树知道根节点的四种遍历思想

    千次阅读 2018-03-09 20:34:00
    * 1,先入栈根节点,输出根节点val值,再先后入栈其右节点、左结点; 25 * 2,出栈左节点,输出其val值,再入栈该左节点的右节点、左节点;直到遍历完该左节点所在子树。 26 * 3,再出栈右节点,输出其...
  • C语言实现二叉树节点删除

    千次阅读 2019-05-02 20:12:46
    二叉树节点删除 C C++
  • 二叉树中第k层节点个数 递归解法: (1)如果二叉树为空或者k返回0 (2)如果二叉树不为空并且k==1,返回1 ...(3)如果给定节点pRoot左右子树不都为NULL,则不是叶子节点,以pRoot为根节点的子树叶子节点数
  • 剑指offer:输入一颗二叉树根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组...
  • 二叉树 完全二叉树
  • 二叉树寻找节点x的所有祖先

    千次阅读 2020-05-24 19:53:35
    节点p从根节点开始一直往右下走并进栈,直到null 若p为null,则令p = stack.top().left,栈顶的那个元素已经没用了,所以并弹出一个元素。 若p为null而且栈为空,说明遍历完成。 struct Node { int data{0}; N
  • 求解二叉树所有节点的深度

    千次阅读 2016-10-05 21:13:04
    如何求解一个二叉树所有节点的深度? 常见的算法是采用递归求解二叉树的最大深度,算法如下: int maxDepth(node *p) { if (!p) return 0; int lh = maxDepth(p->left); int rh = maxDepth(p->right); ...
  • Java实现 LeetCode 222 完全二叉树节点个数

    万次阅读 多人点赞 2020-02-28 19:15:14
    222. 完全二叉树节点个数 给出一个完全二叉树,求出该树的节点个数。 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层...
  • 寻找二叉树某个节点的父节点(递归和非递归两种方法)java代码 寻找二叉树某个节点的父节点(递归和非递归两种方法)java代码 1.非递归式,利用栈来辅助 public TreeNode dfs(TreeNode root, ... //根节点入栈 TreeN

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 171,681
精华内容 68,672
关键字:

如何确定二叉树的根节点