4

I want to find the longest path in a Binary Tree. I plan to add them to a list, that way I can tell my enemy character to take the long path on easy mode.

private static <T> ArrayList<T> depthFirstSearch(BinaryNode<T> node)
{
    if(node != null)
    {
        Stack<BinaryNode<T>> stack = new Stack<BinaryNode<T>>();

        stack.push(node);

        while(!stack.isEmpty())
        {
            BinaryNode<T> currentNode = stack.pop();



            if(currentNode.right != null)
                stack.push(currentNode.right);

            // We want to visit left child first, so push left node last.
            if(currentNode.left != null) 
                stack.push(currentNode.left);
        }
    }
}

I have written that code, but it is a mess. I am trying to use DFS to find the longest path to take. Any suggestions?

EDIT: I do have the height of the tree, I can get it using this.

public static <T> int height(BinaryNode<T> t)
{
    if (t == null)
        return -1;

    else 
        return 1 + Math.max(height(t.left), height(t.right));
}

My issue is: when do I know that I have found the longest path using DFS so that I can add nodes to my list?

Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
Mike John
  • 818
  • 4
  • 11
  • 29
  • 1
    sounds like a homework / assignment . – Raptor Mar 19 '13 at 03:55
  • If you wrote the binary tree class, you can keep a record of its height and width, sometimes useful to determine what type of search to use. – Serdalis Mar 19 '13 at 03:56
  • 2
    You need to define "path". Do you mean root-to-leaf path? Or do you mean the longest path from some leaf to any other leaf? There's a big difference. – Gene Mar 19 '13 at 04:00
  • Yes I will give it the root and from it I will try to find the longest path, which may not be the root. It could be left of root to right of root. For example, in a tree in preFix abc the root is a but the longest path is bac. The root I am passing is just the Tree, it holds no particular meaning besides just holding all the children below. – Mike John Mar 19 '13 at 04:07
  • So any arbitrary path, as long as it is the longest path in the tree? In the context of your question (a game bot) it makes little sense if you do not specify at least the starting position as well? – zz3599 Mar 19 '13 at 04:17
  • Also, if it's a graph, your longest path might be REALLY long, up to visiting all the nodes, and it might not end up being what you actually want. – Vesper Mar 19 '13 at 04:18
  • Yes as long as it is the longest path. I want to make the enemies spawn where the path starts, on that node. – Mike John Mar 19 '13 at 04:20

3 Answers3

8

The longest path in a tree, is called "diameter". You can see the implementation of the algorithm here: http://www.geeksforgeeks.org/diameter-of-a-binary-tree/

Majid Darabi
  • 731
  • 6
  • 15
  • 4
    @Vinay: Diameter of a tree is the longest path! – Majid Darabi May 01 '15 at 20:55
  • @MajidDarabi path in a tree - is a contiguous nodes sequence, that can be traversed only using pointers (to left and right leaves), diameter is not a path! – vladon Nov 07 '15 at 21:00
  • @VladislavYaroslavlev Could you add a reference to your definition of a path in a tree?? (a scientific paper or a book) because based on the general definition of a path in a graph, I could not conclude your definition. https://en.wikipedia.org/wiki/Path_%28graph_theory%29 – Majid Darabi Nov 09 '15 at 18:35
2

Check the answer given by Niki in the following link.. That is O(n) solution

Diameter of Binary Tree - Better Design

Community
  • 1
  • 1
San
  • 5,567
  • 2
  • 26
  • 28
0

I will leave this answer in case any one need it. Here is my solution in c++. The function Get_Max_Path() returns a vector with the longest path itself so you got the path, it's length and it's sum if needed:

vector<int> Max_Path(vector<int>rightpath, vector<int>leftpath)
{
    return (rightpath.size() > leftpath.size()) ? rightpath : leftpath;
}

vector<int> GetPath(node* N, vector<int> v)
{
    v.push_back(N->Data);
    return v;
}
vector<int> Get_Max_Path(node* root)
{
    if (!root) return 
        vector<int>(0);
    return Max_Path(GetPath( root, Get_Max_Path(root->Right)), 
                    GetPath( root, Get_Max_Path(root->Left)) );
}

And here is the tree structure


class node
{
public:
    node* Right = NULL;
    node* Left = NULL;
    int Data;
};

class Tree
{
private:
    node* Root = NULL;

public:

    void Insert_Node(int Data)
    {
        node* DataNode = (node*)malloc(sizeof(node));
        DataNode->Data = Data;
        DataNode->Left = DataNode->Right = NULL;

        if (Root == NULL) {
            Root = DataNode;
            return;
        }

        node* tmp_root = Root, * prev = NULL;
        while (tmp_root != NULL)
        {
            prev = tmp_root;
            tmp_root = (tmp_root->Data < Data) ?
                tmp_root->Right :
                tmp_root->Left;
        }
        (prev->Data < Data) ? (prev->Right = DataNode) : (prev->Left = DataNode);
    }

    vector<int> Max_Path(vector<int>rightpath, vector<int>leftpath)
    {
        return (rightpath.size() > leftpath.size()) ? rightpath : leftpath;
    }
    vector<int> Update_Path(node* N, vector<int> v)
    {
        v.push_back(N->Data);
        return v;
    }
    vector<int> Get_Max_length_Path(node* root)
    {
        if (!root) return
            vector<int>(0);
        return Max_Path(
            Update_Path(root, Get_Max_length_Path(root->Right)),
            Update_Path(root, Get_Max_length_Path(root->Left)));
    }

    vector<int> Get_Max_length_Path()
    {
        return Get_Max_length_Path(Root);
    }
};

This is the driver Code

int main()
{
    Tree T;

    int nodes[] = { 11, 6, 8, 19, 4, 13, 5, 17, 43, 49, 16, 31, 32};
    int length = sizeof(nodes) / sizeof(nodes[0]);

    for (size_t i = 0; i < length; i++)
        T.Insert_Node(nodes[i]);

    int sum = 0;

    vector<int> path = T.Get_Max_length_Path();
    cout << "The path length is : " << path.size() <<endl;
    cout << "The path from the leaf to the root is : ";
    for (int i = 0; i < path.size(); i++)
    {
        cout << path[i] << " ";
        sum += path[i] ;
    }
    cout << endl;
    cout << "the path sum is :" << sum << endl;
    return 0;
}

Test Case

BST sample BST sample

Output

The path length is : 5 The path from the leaf to the root is : 16 17
13 19 11 the path sum is :76
MartenCatcher
  • 2,713
  • 8
  • 26
  • 39