This information is related to what type of tree. In other words, you should recognize that this information The peak of the pyramid(Max Heap), or binary search tree or a combination of both or none of them do not.
Input format is as follows:
(94,RR) (17,L) (36,RL) (51,R) (20,) (76,RRR) ()
Input format each node in the tree for a given pair. The first value represents the amount of Node and the second value represents the root path that must be navigated to get to this node. Node Has no way represents the root of the tree. With this information you should be able to type Identify the tree.
For example, the tree is as follows:
(94,RR) (17,L) (36,RL) (51,R) (20,) (76,RRR) ()
tree for this string
this tree is not a maximum pyramid(max Heap),not a binary search tree and not a combination of there.
Entrance :
At the entrance you get a string that information is relevant to a tree. Each tree
With the statement (s) end. Entry Exit program ends.
Output:
You are one of the following phrases in your printed output.
1.BST: If the input tree is a binary search tree.
2.MaxHeap: If the tree is the maximum pyramid entrance.
3.BST MaxHeap: If the combined input of binary search tree and the pyramid is the maximum.
4.Nothing: If there is none of the above.
**Sample Input:**
(94,RR) (17,L) (36,RL) (51,R) (20,) (76,RRR) ()
(94,) (59,LL) (61,RR) (53,LR) (79,L) (77,R) (15,RL) ()
(72,) (44,LR) (15,L) (2,LL) ()
Exit
**Sample Output:**
Nothing
MaxHeap
BST
Now I cant implementation tree for this question.please help.
Thank you.
Let us represent your data in an array. We can construct a binary tree from that array by using the formula 2*i for the left child of node i and 2*i+1 for the right child of node i. I am also assuming you have your own basic BST ready.
1. How to determine if the given tree is a BST: Sort the input by the size of the String representing the positions of the tree. Your data can be stored in a class called Pair which stores an integer representing the value and a string representing the position relative to the root. We can then sort it. Here's how you can implement the class and the array which stores it:
class Pair
{
int val;
String pos;
Pair(int val, String pos)
{
this.val=val;
this.pos=pos;
}
}
Now in the main method or wherever, you can start building your tree array
int n;
//Take n which is number of nodes here
Pair[] input=new Pair[n];
for(int i=0;i<n;i++)
{
input[i]=new Pair(*input value*, *input Position*);
}
Arrays.sort(input, new Comparator<Book>() //Sorts by the distance from start node
{
#Override
public int compare(Pair p1, Pair p2)
{
return p1.pos.length()-p2.pos.length();
}
});
Now, simply create a recursive method in your BST called Insert(Node curr, int value, String where, int tillWhere)'. I am assuming again, that your BST has aNode` class which stores the data, as well as left and right child references.
class Node //The node for the BSt should look something like this
{
Node left, right;
int data;
Node(Node left, Node right, int data)
{
this.left=left;
this.right=right;
this.data=data;
}
}
<br>
//Method for inserting into the BST
void Insert(Node curr, int value, String where, int tillWhere)
{
if(curr==null)
curr=new Node(value);
else
{
if(where.charAt(tillWhere)=='L')
Insert(curr.left, value, where, tillWhere+1);
else
Insert(curr.right, value, where, tillWhere+1);
}
}
Now, simply perform an In-order traversal of the BST and store the results in the array Inorder. After that if the data is in sorted order, It will be a BST.
ArrayList<Integer> inOrder=new ArrayList<Integer>();
//Method
void Inorder(Node curr)
{
if(curr!=null)
{
if(curr.left!=null)
Inorder(curr.left);
inOrder.add(curr.data); //Appending to list
if(curr.right!=null)
Inorder(curr.right);
}
}
//Now after method call:
boolean isBST(ArrayList<Integer> inOrder)
{
for(int i=1;i<=inOrder.size();i++)
if(inOrder.get(i)<inOrder.get(i-1)) //Not possible in BST
return false;
return true
}
How to determine if given tree is a Heap: Simply satisfy the property that the parent is >= it's children. We can write a simple recursive solution for that like this:
boolean isHeap(int[] arr, int i, int n)// array storing the tree, initial postion , size
{
if (i > (n - 2)/2) //Root
return true;
// If an internal node and is greater than its children, and
// same is recursively true for the children
if (arr[i] >= arr[2*i + 1] && arr[i] >= arr[2*i + 2] &&
isHeap(arr, 2*i + 1, n) && isHeap(arr, 2*i + 2, n))
return true;
return false;
}
You can work out all the 4 conditions in your question from the data I have given you above. I hope this helped!
Related
I want to make a program where you can make nodes and connect them, I wanna make Graphical interface so you can see the graphs. My problem is I need to store the edges in between nodes(vertices) some people at my university told me to use maps?
I've tried to store the nodes with a map structure and making my own pair class:
import java.util.Stack;
public class Node extends Main {
public String data;
int ID;
Boolean IsConnected = false;
public Node(String data, int ID, int Connection ) {
this.data = data;
this.ID = ID;
}
public void Connect(Node N1, Node N2) {
}
public boolean IsConnected(Node N1, Node N2) {
if (map.containsValue(N1) && map.containsKey(N2)) {
System.out.println("connected");
return true;
}
System.out.println("not connected");
return false;
}
}
This addresses one way to logically represent edges of a graph. It does not address how to represent a graph visually.
I'm going to assume the number of nodes needed will be known. If that is not the case, this answer will need to be changed.
A common way to represent edges of a graph is to use an adjacency matrix. Given n Nodes, the simplest adjacency matrix for a directed graph is an 2D array of boolean:
boolean [][] adjacent = new boolean [n][n];
This requires each Node to be associated with an index. One way to do that is to use an array:
Node [] myNodes = new node [n];
Then, finding out if there is an edge between two nodes is simple:
public boolean areConnected (int a, int b) {
return adjacent [a][b];
}
And, they are easy to connect:
public void Connect (int from, int to) {
adjacent [from][to] = true;
}
If you need to search to find the index of a Node, you can add this code:
public int indexOf (Node node) {
int index = -1;
for (int i = 0; i < myNodes.length; ++i) {
if (node.equals (myNode [i]) {
index = i;
break;
}
}
}
public boolean areConnected (Node a, Node b) {
int locA = indexOf (a);
int locB = indexOf (b);
if (locA < 0 || locB < 0) {
return false;
}
return areConnected (locA, locB);
}
NOTE: Please seriously consider overriding equals (Object other) and hashCode() methods. Whether you use an adjacency matrix as described here, or a Collection, the default .equals (Object other) will be equivalent to this == other. That is, it will test if they refer to the same Object. If you want to know if the contents of Node Objects are the same, you need to override equals. If you override equals, you should also override hashCode().
Note: You will want to decide how to guard against the possibility that an invalid index or node will be passed to areConnected or Connect. You might, for example, want to throw an exception.
Note: This assumes a directed graph.
Comment: The beginning of this answer has this statement: "I'm going to assume the number of nodes needed will be known early." "Early" means "before the matrix is constructed". One way to represent an adjacency matrix in which the number of nodes is flexible is to use a List<List<Boolean>>. That can represent a 2D List.
An adjacency matrix is not restricted to boolean. For example, if each Node represented a city, the adjacency matrix might be an int [][] , where each entry represents the number of highway miles between cities. A double might represent the geographic distance. A BigDecimal [][] could represent the price of airfare between the cities. It could be an array of Objects of a class you create.
I was looking at the code challenge from gfg BST to max heap:
Given a Binary Search Tree. Convert a given BST into a Special Max Heap with the condition that all the values in the left subtree of a node should be less than all the values in the right subtree of the node. This condition is applied on all the nodes in the so converted Max Heap.
I could not solve the challenge.
So I had a look at the following solution code:
class Solution
{
public static ArrayList<Integer> list=new ArrayList<>();
static int i=0;
public static void InOrderTraversal(Node root){
if(root == null) return ;
InOrderTraversal(root.left);
list.add(root.data);
InOrderTraversal(root.right);
}
public static void PostOrderTraversal(Node root){
if(root == null )return;
PostOrderTraversal(root.left);
PostOrderTraversal(root.right);
root.data= list.get(i);
i++;
}
public static void convertToMaxHeapUtil(Node root)
{
InOrderTraversal(root);
PostOrderTraversal(root);
}
}
I don't see how this code could change the structure of the tree, as it neither adds nor deletes any nodes.
Here is the second sample testcase copied from gfg official website:
Input BST:
3
/ \
1 5
\ / \
2 4 6
\
7
Expected Max heap output:
7
/ \
3 6
/ \ / \
1 2 4 5
I can't understand how it is working on that test case.
Driver code for the problem:
//{ Driver Code Starts
//Initial Template for Java
import java.util.LinkedList;
import java.util.Queue;
import java.io.*;
import java.util.*;
class Node{
int data;
Node left;
Node right;
Node(int data){
this.data = data;
left=null;
right=null;
}
}
class Tree {
static Node buildTree(String str){
if(str.length()==0 || str.charAt(0)=='N'){
return null;
}
String ip[] = str.split(" ");
// Create the root of the tree
Node root = new Node(Integer.parseInt(ip[0]));
// Push the root to the queue
Queue<Node> queue = new LinkedList<>();
queue.add(root);
// Starting from the second element
int i = 1;
while(queue.size()>0 && i < ip.length) {
// Get and remove the front of the queue
Node currNode = queue.peek();
queue.remove();
// Get the current node's value from the string
String currVal = ip[i];
// If the left child is not null
if(!currVal.equals("N")) {
// Create the left child for the current node
currNode.left = new Node(Integer.parseInt(currVal));
// Push it to the queue
queue.add(currNode.left);
}
// For the right child
i++;
if(i >= ip.length)
break;
currVal = ip[i];
// If the right child is not null
if(!currVal.equals("N")) {
// Create the right child for the current node
currNode.right = new Node(Integer.parseInt(currVal));
// Push it to the queue
queue.add(currNode.right);
}
i++;
}
return root;
}
static void postOrder(Node root)
{
if(root == null)
return;
postOrder(root.left);
postOrder(root.right);
System.out.print(root.data+" ");
}
public static void main (String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t=Integer.parseInt(br.readLine());
while(t > 0){
String s = br.readLine();
Node root = buildTree(s);
Solution g = new Solution();
g.convertToMaxHeapUtil(root);
postOrder(root);
System.out.println();
t--;
}
}
}
// } Driver Code Ends
The code you have presented solves this problem with the knowledge that the output tree does not need to be a complete binary tree. Although the example output show a complete binary tree as output, this is not part of the requirement of the code challenge. The automated tests will only verify that the tree in the output has all the children nodes having lesser values than their parent nodes. It does not verify the shape of the tree.
The author of this solution had the insight to just keep the shape of the tree unchanged, with all its nodes staying where they are, and only move around values in that tree.
The approach to do this is simple: first the values (not the nodes!) are collected in a list with an in-order traversal. Since it is given that the input tree is a BST, the list will get the values in sorted order.
Then the values in that list are each assigned back to the node's data, overwriting their previous values. This time the nodes are visited in post-order, which means that parent nodes will get their values later than their child nodes will get them. Since the list is sorted, this means parent nodes will get greater values than their children have. This is exactly what the test suite will test.
We do note that this solves the challenge in maybe a surprising way, but it is not something you would want to do in practice, as a heap does not provide the expected efficiency if it is not balanced.
So if you had been trying to build a solution where you would get an efficient heap as output, then I can only praise that effort. This is what the goal should be of a programmer building a heap, and it shows why solving code challenges is not always helping one to improve on solving real life coding problems.
In my case, I want to create a binary tree by taking the depth as the input.
For example, if I do tree.create(3), there will generate a binary tree when the depth of the deepest left is three, which means there will be 2^3 - 1 nodes in the tree and the value of all of them will be 0. The index will be 0 - 6 accorndingly.
class Tree<T> {
int depth;
int index;
T value;
public Tree(int index,T value) {
this.index = index;
this.value = value;
}
public static <K> Tree<K> create(int depth){
if(depth >= 1) {
//return a tree with the inputting depth,
//but I don't know how to do in this step
return new Tree(...?)
}
}
}
Which part of knowledge shall I use to achieve this in Java? Thanks!
Usually when working with a binary tree data structure you need to write recursive methods. When writing a recursive method, you need to write a condition that terminates the recursion. In your case, the recursion will end if we have reached the desired depth. In order to determine if we have reached the desired depth, we need to know what that desired depth is and what the current depth is. I will assume that the depth of the root node in the binary tree is zero. This means that for a maximum depth of 3 (as in the example in your question), the deepest level will be level 2. If we have not reached the desired depth, then I need to add a left and a right child node and then call the same method on each of those children and make sure that the depth of the child nodes is one greater than the depth of the parent. So my recursive method needs three parameters:
a node to (possibly) add child nodes to
the current depth
the maximum depth
Note that I don't need to handle the value (or data) that each node contains because you state, in your question, that each node will have the same value. Hence I can simply copy the value from the parent node to each of its children.
Here is a complete example. Note that when I tested it, a depth greater than 25 causes an OutOfMemoryError because there is a limit on how many recursive method invocations can be done.
import java.util.ArrayList;
import java.util.List;
public class BinTree<T> {
BinTreeNode<T> root;
public static <T> BinTree<T> create(int depth, T val) {
if (depth > 0) {
BinTree<T> theTree = new BinTree<>();
theTree.root = new BinTreeNode<>(val);
theTree.addLevel(theTree.root, 0, depth);
return theTree;
}
else {
throw new IllegalArgumentException("Invalid depth: " + depth);
}
}
public void getAllElements(BinTreeNode<T> aNode, List<T> list) {
if (aNode == null) {
return;
}
else {
getAllElements(aNode.left, list);
list.add(aNode.genericObject);
getAllElements(aNode.right, list);
}
}
private void addLevel(BinTreeNode<T> theNode, int level, int deepest) {
if (level == deepest - 1) {
return;
}
theNode.left = new BinTreeNode<>(theNode.genericObject);
theNode.right = new BinTreeNode<>(theNode.genericObject);
addLevel(theNode.left, level + 1, deepest);
addLevel(theNode.right, level + 1, deepest);
}
public static void main(String[] args) {
BinTree<String> aTree = BinTree.create(3, "George"); // max depth = 25
List<String> list = new ArrayList<>();
aTree.getAllElements(aTree.root, list);
System.out.println(list.size());
}
}
class BinTreeNode<T> {
BinTreeNode<T> left, right;
T genericObject;
public BinTreeNode(T obj) {
genericObject = obj;
}
}
Note that I added method getAllElements as a test to see whether the correct number of nodes were created.
I understand that the binary tree can be implemented easily this way:
class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
class BinaryTree {
Node root;
public BinaryTree() {
root = null;
}
}
Also the methods for traversal that I've figured out are:
void printInorder(Node node) {
if (node == null) return;
printInorder(node.left);
System.out.print(node.key + " ");
printInorder(node.right);
}
void printPreorder(Node node) {
if (node == null) return;
System.out.print(node.key + " ");
printPreorder(node.left);
printPreorder(node.right);
}
void printPostorder(Node node) {
if (node == null) return;
printPostorder(node.left);
printPostorder(node.right);
System.out.print(node.key + " ");
}
However, I'm given this starter file where the tree data is in 3 arrays: key[],left[] and right[], so key[] elements are the data of the nodes, left and right elements are the indexes of the left and right child of the ith node, so Node root is keys[0], with left child keys[left[0]] and keys[right[0].
I'm not sure how (or if I need) to convert the 3 arrays into a Binary tree using the Node and BinaryTree classes. Where should the Node and BinaryTree classes should go? Outside of tree_orders? Inside of tree_orders but outside of TreeOrders? (sorry about the "creative" naming convention, not mine)
Do I need to iterate over the three arrays to build the tree nodes?
I tried implementing the insert(int data) and insert(Node n, int data) methods below to convert the arrays into nodes but it doesn't seem to fill the tree.
Node insert(int data) {
root = insert(root, data);
return node;
}
Node insert(Node node, int data) {
if (node == null) {
node = new Node(data)
}
else {
if (node.left == null) insert(node.left, data);
else insert(node.right, data);
}
return node;
}
It's just 5 months that I've started learning programming (picked Java) and I've worked with Trees before but this starter is an OOP puzzle for me, I'll need to recheck my OOP knowledge.
This is an example of how the input and output should show (-1 = null node / 5 = number of given nodes):
Input:
5
4 1 2
2 3 4
5 -1 -1
1 -1 -1
3 -1 -1
Output:
1 2 3 4 5
4 2 1 3 5
1 3 2 5 4
Your question is not very clear. The title asks about traversal but you also have worries about reading 100.000 nodes and about giving nodes a name, and about iteration/recursion slowness. That's a whole muddled bundle of confusion!
The traversal logic you show looks OK at first glance.
Assuming you want to build a binary tree using your Node class from the three arrays you could do this (you don't need the BinaryTree class, it only contains the root Node):
class TreeMaker {
private int[] keys, left, right;
TreeMaker(int[] keys, int[] left, int[] right) {
this.keys = keys;
this.left = left;
this.right = right;
}
public Node make() {
return makeNode(0);
}
private Node makeNode(int index) {
if (index < 0 || index >= keys.length) {
return null;
}
Node node = new Node(keys[index]);
node.left = makeNode(left[index]);
node.right = makeNode(right[index]);
return node;
}
}
I think 100.000 nodes is not that much. Making it should not pose a problem either memory wise or speed wise (unless you start doing complex searching, indexing or other fun stuff). NOTE: after seeing the artificial limitations imposed on the Thread running this code, it might be a problem.
You don't have to store nodes in named variables or otherwise name them. Just making sure the binary tree nodes refer to the correct children is enough.
EDIT: about your starter file
This is total crap:
while (!tok.hasMoreElements())
tok = new StringTokenizer(in.readLine());
Firstly StringTokenizer is a legacy class that should no longer be used (for new code). String.split() is the alternative to use nowadays. Furthermore, creating a new instance of StringTokenizer for each line is unnecessary and wasteful. Are you bound to use this code as-is?
And do I understand that you're supposed to enter your tree data from the command line? Why not read the data from a file so you only have to type it in once?
And how are you supposed to type in a valid binary tree? The values in left[] and right[] are actually indices of the key[], so you will have to figure out, whilst typing, in which index each child node will be stored? Crazy stuff. The person setting you this task much be a little bit sadistic. There are much better ways to store binary trees in a single array, see for example this lecture.
This is also remarkable:
static public void main(String[] args) throws IOException {
new Thread(null, new Runnable() {
public void run() {
try {
new tree_orders().run();
} catch (IOException e) {
}
}
}, "1", 1 << 26).start();
}
Here the class tree_orders (sic.) is run in a Thread with a stack size of 1 << 23. This stack size is a hint to the Java runtime to limit the memory needed to keep track of nested method calls to 8388608 bytes. This is probably intended to either make you hit a limit when implementing this recursively, or to ensure that you don't (I haven't figured out which one it is).
In order to apply my TreeMaker in this example, you could use in the run() method:
public void run() throws IOException {
TreeOrders tree = new TreeOrders();
tree.read();
TreeMaker treeMaker = new TreeMaker(tree.keys, tree.left, tree.right);
Node root = treeMaker.make();
printInorder(root);
printPreorder(root);
printPostorder(root);
}
But I get the impression you are supposed to just implement the three given methods and do the traversal on the existing data structure (3 arrays).
What a poor design, those arrays. Anyway, if you want or need to stick to it, traversing the tree is not too bad:
void printInorder(int index) {
if (index == -1) return;
printInorder(left[index]);
System.out.print(keys[index] + " ");
printInorder(right[index]);
}
Similarly for the other traversal orders. I am assuming -1 in either left or right means no decendant. To print the whole tree, call printInOrder(0) since the root is in index 0.
Edit: I believe your example gives the following arrays:
int[] keys = { 4, 2, 5, 1, 3 };
// indices 0..4
int[] left = { 1, 3, -1, -1, -1 };
int[] right = { 2, 4, -1, -1, -1 };
With these, calling printInorder(0) and then System.out.println() prints:
1 2 3 4 5
NOTE: This IS homework, so please do not give me the answer right out, but pointers would be helpful.
Assignment overview:
(Test each method to ensure that it works properly.)
Generate a binary search with 100 elements added in the correct order - add the numbers 1 through 100 to the tree in the correct order add 1, then 2, then 3, etc.
Generate a binary search with 100 elements add in revers order - add the numbers 100, 99, 98 and so on.
Generate a binary search with 100 randomly generated elements.
The reason I said a linear array in the question is because the root has to be the first element in the array and then add the rest.
I do not have all the other methods required to properly test if the tree was made properly, and I am about to leave for work. However, I am posting below the start of the algorithm that I think will work, just not sure.
public BST(int[] numbers)
{
node root;
node currentParent;
node previousParent = null;
int i = 1; // skip the root, that will be handled manualy
root = new node(numbers[0]); // first element is the root
currentParent = root;
// handle right hand side of binary tree first
while (i > root.getValue())
{
while (i > currentParent.getValue())
{
node newNode = new node (numbers[i]);
currentParent.setRightChild(newNode);
previousParent = currentParent;
currentParent = newNode;
i++;
} // end inner while
if (previousParent.leftChild == null)
{
node newNode = new node(numbers[i]);
previousParent.leftChild = newNode;
currentParent = newNode;
i++;
} // end if branch
else
{
System.out.println("Hmm, something seems to be wrong!");
} // end else
} // end right side binary tree while
} // end integer array constructor
This is pretty much the whole algorithm, I would have to do it again but reverse the < and > signs (if this is correct). Am I on the right path with this algorithm?
Adding the node class as requested.
public class node
{
node leftChild; // left pointer
node rightChild; // right pointer
int value; // will be the int value inside the node
boolean isLeaf; // boolean for determing if a node is a left node or not
/*
Null constructor for the class. Sets the pointers to null
*/
public node ()
{
leftChild = null;
rightChild = null;
} // end null constructor
/*
Intialzing constructor that will take a single integer as input
*/
public node (int number)
{
leftChild = null;
rightChild = null;
value = number;
} // end intialzing constructor with int input
/*
The setValue method will take the int value inputted from the array into
a new node
*/
public void setValue(int number)
{
value = number;
} // end setValue()
/*
The getValue method will return to the user the value that is stored
inside a specific node.
*/
public int getValue()
{
return value;
} // end getValue()
/*
The setLeftChild method will set the pointers to the nodes left child
which will be a value that is equal or lower to the paret node
*/
public void setLeftChild (node leftChild)
{
this.leftChild = leftChild;
} // end setLeftChild()
/*
The setRightChild method will be the same as setLeftChild above but will
handle setting the nodes right child. The right child will be a value
that is greater than the parent node
*/
public void setRightChild(node rightChild)
{
this.rightChild = rightChild;
} // end setRightChild
/*
the getLeftChild method will return to the user/calling method what the
left child of a given node is.
*/
public node getLeftChild (node currentNode)
{
return leftChild;
} // end getLeftChild()
/*
the getRightChild method is exactly the same as the getLeftChil method
above, except it will return the right child instead
*/
public node getRightChild(node currentNode)
{
return rightChild;
} // end getRightChild()
/*
The setLeaf method will be in charge of manipulating a boolean value and
setting it to true if the node is a left or not
*/
public void setLeaf(boolean leaf)
{
if (leaf == true)
{
isLeaf = true;
} // end if
else
{
isLeaf = false;
} // end else
} // end setLeaf
/*
The getLeaft method will simply return a boolean value that indicates if
the given node is a left node or not
*/
public boolean getLeaf()
{
return isLeaf;
} // end getLeaf()
} // end node class
No, sorry, this is wrong.
You are comparing indices with data values. You should only compare the same things to the same things. Imagine the task is to put the numbers 1001 through 1100 into the tree, rather than 1 through 100. It will make it easier to distinguish between indices and data values (and the distinction is very subtle here because your indices are 0 through 99 and your data values 1 through 100).
You cannot assume that you "handle the right hand part first". You have to decide whether the given item will go left or right based on its value, and whether it's less than or greater than the current node's value.
Trying to add all high values first and then all low values will not work, if you have an unordered array.
One last tip: the class should be named Node, not node. Classes and all type names should start with a capital, variables, fields and method names should start with a lowercase letter, and constants should be in all-caps.