6

I need to create an unsorted binary tree (one requirement is that it is unsorted) that holds a String as its value. My class outline looks like this:

public class Node {

 private String desc;
 private Node leftNode = null;
 private Node rightNode = null;

 public Node(String desc) {
  this.desc = desc;
 }

 public String getDesc() {
  return desc;
 }

 public Node getLeftNode() {
  return leftNode;
 }

 public Node getRightNode() {
  return rightNode;
 }
}

Eventually I want to be able to replace any node that matches a String description with a new node that has a new description (including duplicates with the old description).

So my question is, what is the best way to handle the insertion of Nodes when creating an unsorted binary tree?

I thought of two ways. The first would be to just have two methods, setLeftNode(Node root, String desc) and setRightNode(Node root, String desc) that someone could call with a Node of their choice as the root. If there already is a left/right Node, then it would just advance down until it hit a node that didn't have a left Node. But this could introduce problems by producing super large heights.

The second way I thought of would be to have a dedicated root Node, in this case the first Node created, and then to just build new Nodes in order.

So what is the best way to create an unsorted binary tree?

Alex
  • 1,927
  • 3
  • 28
  • 54
  • 2
    The most efficient way of creating an unsorted binary tree from a list of items is just to take the list of items and consider element 0 the root, element 1 and 2 the left and right nodes of element 0, etc. This gives you a perfectly balanced tree with zero work. But what's the point of this tree in the first place? – that other guy May 10 '15 at 01:16
  • @Alex as per my understanding a regular Binary Tree is always unsorted. – akhil_mittal May 10 '15 at 01:28
  • @Alex if you are looking for a `Binary Search Tree` then obviously it has its own well defined ordering scheme. For Binary Tree there is no best way as such it all depends on how you want to do it, based on your requirements. – akhil_mittal May 10 '15 at 02:00

5 Answers5

3
public class BinaryTree{
    private BinaryTree right;
    private BinaryTree left;
    private String data;        

    public BinaryTree(String s){
        data = s;
        right = null;
        left = null;           
    }

    public void setLeft (BinaryTree l){ left  = l; }
    public void setRight(BinaryTree r){ right = r; }        
}

Your question suggests that the tree should be balanced and so on insertion of an element, you should recursively check number of nodes at each side of the tree:

public int checkTree(){
    if(left == null && right == null){
        return 1;
    }else if(left == null){
        return 1 + right.checkTree();
    }else if(right == null){
        return 1 + left.checkTree();
    }else{
        return 1 + left.checkTree() + right.checkTree();
    }
}

public void insert(BinaryTree bt){
    if(left == null){
        setLeft(bt);
    }else if(right == null){
        setRight(bt);
    }else{
        if(left.checkTree() <= right.checkTree()){
            left.insert(bt);
        }else{
            right.insert(bt);
        }
    }
}






EDITED:

public class BinaryTree {
    private BinaryTree right;
    private BinaryTree left;
    private String data;
    private int weight;

    public BinaryTree(String s){
        data = s;
        right = null;
        left = null; 
        weight = 1;
    }    

    public void setLeft (BinaryTree l){ 
        left  = l;
        weight++;
    }

    public void setRight(BinaryTree r){
        right = r;
        weight++;
    } 

    public int getWeight(){ return weight; }

    public void insert(BinaryTree bt){
        if(left == null){
            setLeft(bt);
        }else if(right == null){
            setRight(bt);
        }else{
            if(left.getWeight() <= right.getWeight()){
                left.insert(bt);
                weight++;
            }else{
                right.insert(bt);
                weight++;
            }
        }
    }    
}    
Suspended
  • 1,054
  • 2
  • 10
  • 26
  • What exactly is the need of `(left == null && right == null) || left == null)` in insertion? And what is `checkTree()` actually trying to do? – akhil_mittal May 10 '15 at 01:59
  • The need of (left == null && right == null) || left == null) is to check whether subtrees are null, because we can't call insert() on null value - it has to be a tree. checkTree() recursively counts number of nodes and by comparing values returned from left subtree and right subtree, we can always select the right branch to call insert() on. insert() is - as you can see - also recursive and it will go into a branch until it finds the source of imbalance. This way our tree is always balanced. – Suspended May 10 '15 at 02:12
  • Don't you think `if(left == null) setLeft(bt);` will also work? Why need to check both nodes? For balancing your tree IMO this recursive solution is too much of overhead. Imagine you want to insert 10000 nodes. – akhil_mittal May 10 '15 at 02:18
  • if(left == null) setLeft(bt); - yes, you're right. About the overhead, balancing is always expensive but obviously there are other ways to do that. Insertion speed could be improved by introducing additional attribute, which would hold number of nodes in subtrees and be updated with each insertion. Gain speed by sacrificing some memory. On the other hand, some memory would also be freed, cause we wouldn't need checkTree() method anymore :) – Suspended May 10 '15 at 02:32
  • 1
    Trust me, recursive methods are mostly not the preferred choice in a real world project :) – akhil_mittal May 10 '15 at 02:39
  • Trust me, @akhil_mittal is over generalizing. :-| – Stephen C May 11 '15 at 10:08
  • Stephen C: IMO, the recursive methods generally do not perform well for huge data set where computation takes lot of time and memory. Please correct me if I am wrong :) – akhil_mittal May 11 '15 at 10:10
1

by definition a binary tree has its lowest elements on the left, and the highest on the right. But if you really want that all messed up (sorted) you can call a rand function that results in 0 or 1, and if 0 then go to left, if 1 go to right, randomly. That will result in an unsorted tree

João Vilaça
  • 571
  • 5
  • 13
  • 4
    A **Binary Search Tree** is an ordered binary tree, no? Meaning Binary Tree elements are not always ordered with the smallest elements on the left/largest elements on the right. – freddiev4 May 10 '15 at 01:13
  • `a binary tree has its lowest elements on the left, and the highest on the right` Can you please elaborate? – akhil_mittal May 10 '15 at 01:45
  • IMO you are wrong. Please refrain from posting wrong answers. – akhil_mittal May 10 '15 at 01:51
  • "A binary search tree is a rooted binary tree, whose internal nodes each store a key (and optionally, an associated value) and each have two distinguished sub-trees, commonly denoted left and right. The tree additionally satisfies the binary search tree property, which states that the key in each node must be greater than all keys stored in the left sub-tree, and smaller than all keys in right sub-tree.[1] (The leaves (final nodes) of the tree contain no key and have no structure to distinguish them from one another." , from Wikipedia – João Vilaça May 10 '15 at 01:52
  • 1
    A `Binary Tree` is not exactly same as `Binary Search Tree` and OP asked for `Binary Tree`. – akhil_mittal May 10 '15 at 01:57
  • you're correct. i'm sorry for my mistake, it's 3am here and i just wanted to help. Thank you. – João Vilaça May 10 '15 at 01:59
  • I respect you spirit to help but please assure you know well what you are going to post. Directing him in wrong direction will do no good either to you or OP. – akhil_mittal May 10 '15 at 02:02
1

Eventually I want to be able to replace any node that matches a String description with a new node that has a new description (including duplicates with the old description).

For that you will have to search your entire tree as:

private Node searchBasedOnValue(String desc, Node currentNode)
{  
    Node result = null
    if (currentNode == null)
        return null;
    if (currentNode.getDesc().equals(desc)) 
        return currentNode ;
    if (currentNode.getLeftNode() != null)
        result = searchBasedOnValue(desc,currentNode.getLeftNode());
    if (result == null)
        result = searchBasedOnValue(desc,currentNode.getRightNode());
    return result;
}

IMO, a regular Binary Tree is never sorted the one which is sorted is called Binary Search Tree. For insertion you need to handle the way you want it. May be you can insert nodes alternatively to left and right child of your tree so that it is balanced to some extent. That is up to you how you take care of that.

I have not seen much practical usage for regular Binary Tree as most of the times we use Binary Search Tree which have better performance (lg(n)) in terms of insertion, deletion and lookup.

akhil_mittal
  • 18,855
  • 7
  • 83
  • 82
0

If it is unsorted, why build a binary tree at all? You can't search it without doing a full scan, so you might as well put everything in an array, as accessing any element will be O(n), due to the inability to search.

Edwin Buck
  • 64,804
  • 7
  • 90
  • 127
0

This is the fastest way to build an unsorted binary tree without any constraints on its shape:

First you need a constructor like this:

   public Node(String desc, Node left, Node right) {
       this.desc = desc;
       this.left = left;
       this.right = right;
   }

Then build the tree like this:

   Node root = null;
   for (String input: ...) {
      root = new Node(input, root, null);
   }

Obviously, this gives you an unbalanced, unsorted tree for which searching entails looking at all of the nodes. However, if the tree is unsorted, then the fact that the tree is unbalanced makes no difference.

In general, searching an unsorted tree has the same complexity as searching a list, and the code is more complex.

Stephen C
  • 632,615
  • 86
  • 730
  • 1,096