The maximum distance of a node in a binary tree

Source: Internet
Author: User
Tags printf

Problem definition

Consider the two-fork tree as a graph, the connection between the parent and child nodes is bidirectional, and the distance is defined as the number of sides between the two nodes. For example, the maximum distance in the figure below is a red line number of 6.

Analysis


Method One,

typedef struct Node {struct node *pleft;    Left child struct Node *pright;           Right child char Chvalue;       The value of the node int leftmaxvalue;      Zuozi maximum distance int rightmaxvalue;  
  
Right subtree longest distance}lnode, *bintree;  
  
    void Findmaxlen (bintree root, int *maxlen) {//Traversal to leaf node, return if (root = NULL) return;  
  
    If the left dial hand tree is empty, the maximum distance to the left of the node is 0 if (root->pleft = = NULL) Root->leftmaxvalue = 0;  
  
    If the right subtree is empty, the maximum distance to the right of the node is 0 if (root->pright = = NULL) Root->rightmaxvalue = 0;  
  
    If the left dial hand tree is not empty, recursively looks for the left subtree longest distance if (root->pleft! = NULL) Findmaxlen (Root->pleft, MaxLen);  
  
    If the right subtree is not empty, recursively look for the right subtree longest distance if (root->pright! = NULL) Findmaxlen (Root->pright, MaxLen); Calculates the longest distance from the root node in the left subtree if (root->pleft! = NULL) {if (Root->pleft->leftmaxvalue > Root->pleft-&gt  ; rightmaxvalue) Root->leftmaxvalue = Root->pleft->leftmaxvalue + 1;
        else Root->leftmaxvalue = root->pleft->rightmaxvalue + 1; }//calculates the longest distance from the root node in the right subtree if (root->pright! = NULL) {if (Root->pright->leftmaxvalue > root-  
        >pright->rightmaxvalue) Root->rightmaxvalue = Root->pright->leftmaxvalue + 1;  
    else Root->rightmaxvalue = root->pright->rightmaxvalue + 1; }//update longest distance if (Root->leftmaxvalue + root->rightmaxvalue > *maxlen) *maxlen = Root->lef  
Tmaxvalue + root->rightmaxvalue;   }

The maximum distance between the current two nodes is always stored in int *maxlen and is updated during traversal.

The program described below is intended to test whether the above code is correct, including establishing a two-fork tree, destroying a binary tree, and printing a binary tree:

#include <stdlib.h> #include <stdio.h> typedef struct Node {struct node *pleft;    Left child struct Node *pright;           Right child char Chvalue;       The value of the node int leftmaxvalue;      Zuozi maximum distance int rightmaxvalue;  
  
Right subtree longest distance}lnode, *bintree;  
  
    void Findmaxlen (bintree root, int *maxlen) {//Traversal to leaf node, return if (root = NULL) return;  
  
    If the left dial hand tree is empty, the maximum distance to the left of the node is 0 if (root->pleft = = NULL) Root->leftmaxvalue = 0;  
  
    If the right subtree is empty, the maximum distance to the right of the node is 0 if (root->pright = = NULL) Root->rightmaxvalue = 0;  
  
    If the left dial hand tree is not empty, recursively looks for the left subtree longest distance if (root->pleft! = NULL) Findmaxlen (Root->pleft, MaxLen);  
  
    If the right subtree is not empty, recursively look for the right subtree longest distance if (root->pright! = NULL) Findmaxlen (Root->pright, MaxLen); Calculates the longest distance from the root node in the left subtree if (root->pleft! = NULL) {if (Root->pleft->leftmaxvalue > Root->pleft-&gt ; rightmaxvalue) Root->leftmaxvalue = Root->pleft->leftmaxvalue + 1;  
    else Root->leftmaxvalue = root->pleft->rightmaxvalue + 1; }//calculates the longest distance from the root node in the right subtree if (root->pright! = NULL) {if (Root->pright->leftmaxvalue > root-  
        >pright->rightmaxvalue) Root->rightmaxvalue = Root->pright->leftmaxvalue + 1;  
    else Root->rightmaxvalue = root->pright->rightmaxvalue + 1; }//update longest distance if (Root->leftmaxvalue + root->rightmaxvalue > *maxlen) *maxlen = Root->lef  
Tmaxvalue + root->rightmaxvalue;  
    }//Create two fork tree void Buildbintree (Bintree *root) {char ch;    scanf ("%c", &ch);  
    Enter an element fpurge (stdin);  
    if (ch = = ")//if the input is a space character, indicating that the binary tree is empty, the *root is null *root = NULL;  
        else {//If the input is not a space character, the value is assigned to the root node's chvalue, and the Saozi right subtree *root = (bintree) malloc (sizeof (Lnode)) is established recursively; (*root)-&GT;CHValue = ch;  
        (*root)->leftmaxvalue = 0;  
  
        (*root)->rightmaxvalue = 0;  
        Buildbintree (& (*root)->pleft);  
    Buildbintree (& (*root)->pright); }}//Destroy binary tree, free memory void Destroybintree (Bintree *root) {if (*root! = NULL) {Destroybintree (& (  
        *root)->pleft);  
  
        Destroybintree (& (*root)->pright);  
        Free (*root);  
    *root = NULL; }}//Pre-order traversal binary tree void Preordertraverse (Bintree root) {if (root = NULL) {preordertraverse (ROOT-&G  
        T;pleft);  
        printf ("%c", Root->chvalue);  
    Preordertraverse (Root->pright);  
    }} int main () {Bintree root;  
    Buildbintree (&root);  
    Preordertraverse (root);  
    printf ("\ n");  
    int maxlen = 0;  
    Findmaxlen (Root, &maxlen);  
    printf ("MaxLen =%d\n", maxlen);  
Destroybintree (&root);   }

This code has several drawbacks: the algorithm joins the intrusive (intrusive) data nmaxleft, Nmaxright uses the global variable Nmaxlen. Additional initialization is needed for each use. And even with different independent data, it is not possible to use this function logic in multiple threads, and there are many NULL-related conditional tests.

Method Two,

Definition: In a subtree with node x as the root node, the maximum distance between nodes is dis (x).

Above, the largest dis (root node) in the left image and the largest dis (root node->left) in the right image. From the top you can see that each node can become the maximum distance root node potential.

Therefore, each dis (node) can be obtained, and the maximum value is the maximum value of the root node of the whole binary tree.

When the maximum distance of x is obtained, the two points of maximum distance may appear in three cases Zuozi right subtree feast point x

After analysis of the following characteristics of the above three cases will eventually be a leaf end in the third case must be Zuozi height and the height of the right subtree (only in this way, it is possible to obtain the maximum value)

After the above analysis, we can get the recursive type

Dis (x) = max (DIS (x->left), Dis (x->right), height (x->left) +height (x->right))

Reference Code

int treedistance (bitree root)
{
    if (root = NULL)
        return 0;
    else if (Root->left = = NULL && Root->right = = null)
        return 0;
    int dis = max (height (root->left) + height (root->right), Treedistance (Root->left), Treedistance (root-> right));
    if (Maxdis < dis)
        maxdis = dis;
    return dis;
}
Here's a trick: Maxdis is a global variable, and the recursive root node iterates over each node, during which time the Maxdis is compared, resulting in the maximum value, without the need for additional space.
Full Run code

#include <iostream> using namespace std;
    typedef struct BITNODE {Bitnode *left;
Bitnode *right;

}bitnode, *bitree;

int Maxdis = 0;
    void Createtree (Bitree &root) {Bitree left1 = new (Bitnode);
    
    Bitree right1 = new (Bitnode);
    Left1->left = NULL;
    Left1->right = NULL;
    Right1->left = NULL;

    Right1->right = NULL;
    Root->left = LEFT1;


    Root->right = right1;
    Bitree left2 = new (Bitnode);
    Left2->left = NULL;
    Left2->right = NULL;
    Bitree right2 = new (Bitnode);
    Right2->left = NULL;
    Right2->right = NULL;
    Left1->left = left2;

    Left1->right = right2;
    Bitree left3 = new (Bitnode);
    Left3->left = NULL;
    Left3->right = NULL;
    Bitree right3 = new (Bitnode);
    Right3->left = NULL;
    Right3->right = NULL;
    Left2->left = left3;
Left2->right = RIGHT3;
        } void DeleteTree (Bitree root) {if (root) {deletetree (root->left); DelEtetree (Root->right);
        Delete (root);
    root = NULL;
    }} int height (bitree root) {if (root = NULL) return 0; else return height (root->left) > Height (root->right)?
Height (root->left) + 1:height (root->right) + 1;
    } int max (int A, int b, int c) {int tmp = a > b? a:b; return tmp > C?
TMP:C;
    } int treedistance (Bitree root) {if (root = NULL) return 0;
    else if (Root->left = = NULL && Root->right = = null) return 0; int dis = max (height (root->left) + height (root->right), Treedistance (Root->left), Treedistance (root->
    right));
    if (Maxdis < dis) Maxdis = dis;
return dis;
    } int main () {Bitree root = new (Bitnode);
    Root->right = Root->left = NULL;    
    Createtree (root);
    cout << "Height:" << height (root) << Endl;
    cout << "treedistance:" << treedistance (Root) << Endl; cout << "_____________________ "<< Endl;
DeleteTree (root); }
Results
4

Method Three,


I think the core of the problem is that situations A and B need different information: a requires the maximum depth of the subtree, and B requires the maximum distance of the subtree. As long as the function can compute and return both messages at one node, the code can be simple:

#include <iostream>
 
using namespace std;
 
struct node
{
    node *pleft;
    NODE *pright;
};
 
struct RESULT
{
    int nmaxdistance;
    int nmaxdepth;
};
 
Result Getmaximumdistance (node* root)
{
    if (!root)
    {
        RESULT empty = {0,-1};   Trick:nmaxdepth is-1 and then caller'll plus 1 to balance it as zero.
        return empty;
    }
 
    RESULT LHS = getmaximumdistance (root->pleft);
    RESULT RHS = getmaximumdistance (root->pright);
 
    result result;
    result.nmaxdepth = max (lhs.nmaxdepth + 1, rhs.nmaxdepth + 1);
    Result.nmaxdistance = Max (max (lhs.nmaxdistance, rhs.nmaxdistance), lhs.nmaxdepth + rhs.nmaxdepth + 2);
    return result;
}

The code for the calculation of result is clear: Nmaxdepth is the Saozi of the right subtree and the maximum value for the case of A and B 1;nmaxdistance.

To reduce the conditional test for NULL, when entering a function, if the node is null, an empty variable is passed back. It is strange that empty.nmaxdepth =-1, the purpose is to let the caller +1, the current non-existent (NULL) subtree as the maximum depth of 0.

In addition to improved readability, another advantage of this solution is to reduce the size of the O (number of nodes) of intrusive data, and instead use O (maximum depth of the tree) size of the stack space. This design makes the function completely free of side effects (side effect).




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.