Summary of common algorithms for binary trees (1)

1. In a binary tree, find the distance between the two farthest nodes


In a binary tree, find the distance between the two furthest nodes. In the above binary tree, the distance of the farthest node is: 4 (the path is 2-3-13-5-2).

Solution: traverse each node, find the longest path with the current node as the root, and then find the maximum value among all the longest paths. The idea is similar to the maximum path sum .
The code is given directly below.
void longestPathUtil(Node* root, int& left_len, int& right_len, int& max_len);  
int longestPath(Node* root)  
{  
    int left_len, right_len, max_len;  
    longestPathUtil(root, left_len, right_len, max_len);  
    return max_len;  
}  
  
void longestPathUtil(Node* root, int& left_len, int& right_len, int& max_len)  
{  
    if(root==NULL)  
    {  
        left_len = 0;  
        right_len = 0;  
        max_len = 0;  
        return;  
    }  
  
    int left_len1, right_len1, left_len2, right_len2;  
    longestPathUtil(root->left, left_len1, right_len1, max_len);  
    longestPathUtil(root->right, left_len2, right_len2, max_len);  
  
    left_len = 1+max(left_len1, right_len1);  
    right_len = 1+max(left_len2, right_len2);  
    max_len = max(left_len+right_len-1, max_len);   
}  


Or look at the following analysis, transferred from: http://blog.csdn.net/caryaliu/article/details/8107089#

Source of the problem: "The Beauty of Programming" 3.8 Find the Maximum Distance of Binary Tree Nodes

If the binary tree is regarded as a graph, the connection between the parent and child nodes is regarded as bidirectional, let us define "distance" as the number between two nodes.

Write a program to find the distance between the two furthest nodes in a binary tree.

As shown in the image below, the sides of the thick arrows represent the longest distances:


The two nodes farthest apart in the tree are A, B

Analysis shows that for a binary tree, if two nodes U and V are the farthest apart, there are two situations:

1. The path from the U node to the V node goes through the root node

2. The path from the U node to the V node does not pass through the root node. In this case, the U and V nodes must be on the left subtree or the right subtree of the root node, which is transformed into the child of the root node. The distance between the two furthest nodes in a binary tree whose node is the root node

The above-mentioned passing through the root node means that the path contains the root node. For example, if only the left subtree FGHA is added in the above figure, then the two nodes with the longest distance are F and A, and the root node F is included in the path. called through the root node.

So we can solve it recursively, traverse the binary tree according to the in-order traversal method of the binary tree, and find the two nodes that are farthest apart during the traversal process.

The program description is as follows:

typedef struct Node {  
    struct Node *pleft;     //左孩子  
    struct Node *pright;    //右孩子  
    char chValue;           //该节点的值  
  
    int leftMaxValue;       //左子树最长距离  
    int rightMaxValue;      //右子树最长距离  
}LNode, *BinTree;  
  
void findMaxLen(BinTree root, int *maxLen) {  
    //遍历到叶子结点,返回  
    if(root == NULL)  
        return;  
  
    //如果左子树为空,那么该节点左边最长距离为0  
    if(root->pleft == NULL)  
        root->leftMaxValue = 0;  
  
    //如果右子树为空,那么该节点右边最长距离为0  
    if(root->pright == NULL)  
        root->rightMaxValue = 0;  
  
    //如果左子树不为空,递归寻找左子树最长距离  
    if(root->pleft != NULL)  
        findMaxLen(root->pleft, maxLen);  
  
    //如果右子树不为空,递归寻找右子树最长距离  
    if(root->pright != NULL)  
        findMaxLen(root->pright, maxLen);  
  
    //计算左子树中距离根节点的最长距离  
    if(root->pleft != NULL) {  
        if(root->pleft->leftMaxValue > root->pleft->rightMaxValue)  
            root->leftMaxValue = root->pleft->leftMaxValue + 1;  
        else  
            root->leftMaxValue = root->pleft->rightMaxValue + 1;  
    }  
  
    //计算右子树中距离根节点的最长距离  
    if(root->pright != NULL) {  
        if(root->pright->leftMaxValue > root->pright->rightMaxValue)  
            root->rightMaxValue = root->pright->leftMaxValue + 1;  
        else  
            root->rightMaxValue = root->pright->rightMaxValue + 1;  
    }  
  
    //更新最长距离  
    if(root->leftMaxValue + root->rightMaxValue > *maxLen)  
        *maxLen = root->leftMaxValue + root->rightMaxValue;  
}  



Second, find the depth and width of the binary tree
The depth of the binary tree: the level of the root node of the binary tree is 1, the level of the child node of the root node is 2, and so on. Depth refers to the number of layers where the deepest node among all nodes is located.

        The width of the binary tree: the maximum number of cotyledons contained in all depths .

//求二叉树的深度  
int GetDepth(tagBiNode *pRoot)  
{  
    if (pRoot == NULL)  
    {  
        return 0;  
    }  
  
    //  int nLeftLength = GetDepth(pRoot->m_left);  
    //  int nRigthLength = GetDepth(pRoot->m_right);  
    //  return nLeftLength > nRigthLength ? (nLeftLength + 1) : (nRigthLength + 1);  
  
    return GetDepth(pRoot->left) > GetDepth(pRoot->right) ?   
        (GetDepth(pRoot->left) + 1) : (GetDepth(pRoot->right) + 1);  
}  
  
//求二叉树的宽度  
int GetWidth(tagBiNode *pRoot)  
{  
    if (pRoot == NULL)  
    {  
        return 0;  
    }  
  
    int nLastLevelWidth = 0;//记录上一层的宽度  
    int nTempLastLevelWidth = 0;  
    int nCurLevelWidth = 0;//记录当前层的宽度  
    int nWidth = 1;//二叉树的宽度  
    queue<BiNode *> myQueue;  
    myQueue.push(pRoot);//将根节点入队列  
    nLastLevelWidth = 1;      
    tagBiNode *pCur = NULL;  
  
    while (!myQueue.empty())//队列不空  
    {  
        nTempLastLevelWidth = nLastLevelWidth;  
        while (nTempLastLevelWidth != 0)  
        {  
            pCur = myQueue.front();//取出队列头元素  
            myQueue.pop();//将队列头元素出对  
  
            if (pCur->left != NULL)  
            {  
                myQueue.push(pCur->left);  
            }  
  
            if (pCur->right != NULL)  
            {  
                myQueue.push(pCur->right);  
            }  
  
            nTempLastLevelWidth--;  
        }  
  
        nCurLevelWidth = myQueue.size();  
        nWidth = nCurLevelWidth > nWidth ? nCurLevelWidth : nWidth;  
        nLastLevelWidth = nCurLevelWidth;  
    }  
  
    return nWidth;  
}  

3. Binary tree series - depth of binary tree, example [LeetCode]

The most notable aspect of the concept of depth in a binary tree is the distance to the "leaf" nodes.

Generally speaking, if you directly say "depth", it refers to the maximum depth, that is, the distance from the farthest leaf.

1. Minimum depth of binary tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

// Definition for binary tree
 struct TreeNode {
     int val;
     TreeNode *left;
     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 };

 class Solution {
 public:
     int minDepth(TreeNode *root) {
     }
 };

Because the depth is the distance from the leaf node, when using depth traversal, you cannot simply compare the recursive results of the left and right subtrees to return a smaller value, because for a node with a single empty child, the empty child will return 0, but This node is not a leaf node, so the returned result is wrong.

Therefore, when a single child of the currently processed node is found to be empty, a maximum value of INT_MAX is returned to prevent it from interfering with the result.

 class Solution {
 public:
     int minDepth(TreeNode *root) {
         if(!root) return 0;
         if(!root -> left && !root -> right) return 1;   //Leaf means should return depth.
         int leftDepth = 1 + minDepth(root -> left);
         leftDepth = (leftDepth == 1 ? INT_MAX : leftDepth);
         int rightDepth = 1 + minDepth(root -> right);
         rightDepth = (rightDepth == 1 ? INT_MAX : rightDepth);  //If only one child returns 1, means this is not leaf, it does not return depth.
        return min(leftDepth, rightDepth);
    }
};

Of course, this problem can also be done with hierarchical traversal.

class Solution {
struct LevNode{
    TreeNode* Node;
    int Lev;
};
public:
    int minDepth(TreeNode *root) {
        if(NULL == root) return 0;
        queue<LevNode> q;
        LevNode lnode;
        lnode.Node = root;
        lnode.Lev = 1;
        q.push(lnode);
        while(!q.empty()){
            LevNode curNode = q.front();
            q.pop();
            if(NULL == (curNode.Node) -> left && NULL == (curNode.Node) -> right)
                return (curNode.Lev);
            if(NULL != (curNode.Node) -> left){
                LevNode newNode;
                newNode.Node = (curNode.Node) -> left;
                newNode.Lev = (curNode.Lev + 1);
                q.push(newNode);
            }
            if(NULL != (curNode.Node) -> right){
                LevNode newNode;
                newNode.Node = (curNode.Node) -> right;
                newNode.Lev = (curNode.Lev + 1);
                q.push(newNode);
            }
        }
        return 0;
    }
};

For this question, both LeetCode solutions take 48ms 

2. Maximum depth of a binary tree

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

The maximum depth is also the length to the leaf node, but because it is the maximum depth, a non-leaf node with a single empty child will not interfere with the result, so it can be done in the most concise way.

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode *root) {
        if(!root) return 0;
        int leftDepth = maxDepth(root -> left) + 1;
        int rightDepth = maxDepth(root -> right) + 1;
        return max(leftDepth, rightDepth);
    }
};



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324449894&siteId=291194637