I try to add every node into one result in iterate way in Java.
For example: if I have a root 5 which has got right node = 7 and left node=3 the result is 15.
I've tried in many ways but I don't know how not to miss any node when my tree is extensive.
I would be grateful for every tip.
Look up tree traversals. There are three basic types: in-order, pre-order, and post-order. Essentially you need to create a function that accepts a node as a parameter and returns an integer.
Assuming you have a node like this:
struct Node {
int value;
Node *right, *left;
}
Something like this would do the trick.
int tree_sum(Node *root) {
if (root == nullptr) return 0; // stops recursion. occurs at leaves
return root->value + tree_sum(root->left) + tree_sum(root->right);
}
Call the function on the root of your tree. This is known as a pre-order traversal. I wrote the code in C++ because I don't know Java.
For tree traversal without recursion use a stack as described here:
https://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/
Related
Just a disclamer, I am doing this for a homework, it's mainly focused on effiency of data structures though.
For a binary search tree i need to implement the delete function, i already created the main traversal system and the only thing i am left doing is to swap the values of a root with the minimal value of it's right subtree, in the case of left and right children. The way i am doing that is through a find the minimal node function.
public int findMin (Tree r1){
int min = r1.key;
while (r1.l != null) {
min = root.l.num;
r1 = r1.l;
}
return min;
}
Great, i found the node i am supposed to delete, my question is, is there a way to also delete the minimal node, without having to traverse the whole tree up until that same node again? Maybe through the function again? Does this function also delete the node or is that not parsed through
I am studying binary trees. I saw online a code to traverse the entire binary tree. Here's the code I got:
'''
public void showAll(Node node)
{
Node parent = node;
if(parent != null)
{
System.out.println(" " + parent.person);
showAll(parent.leftChild);
showAll(parent.rightChild);
}
}
'''
What I dont understand is how this function can print the right child? According to code everytime the function is called left child is printed. The code never reaches the right child.
This is a textbook implementation of postorder traversal. Also known by some as "bottom up" traversal.
For each iteration the leftmost node then the rightmost node is printed. If the parent node is ever null then the tree is past the highest node, i.e. the algorithm has finished.
Try to dry run the code with binary tree having, say 5 nodes. And then you'll probably figure it out. Even then if you are facing problems, learn a little about how a compiler calls functions or what actually stacktrace is.
I have a problem that I am running into a few issues with, the question is as follows:
Given a pre-constructed Binary Search Tree and an array, determine if the array will produce the same Binary Search Tree.
Now, this question will have a pre-constructed BST for you, and then it will run through the following code:
boolean valid = true;
for (int i = 0;valid && i < arr.length; i ++) {
valid &= tree.checkPattern(arr[i]);
}
//These two methods below are in a different class. For every element in the array,
//the checkPattern method will be called, initially passing in the root of the BST
public void checkPattern(int key) {
recursiveFunction(root, key);
}
public boolean recursiveFunction(TreeNode current, int key){
// Recursive function
}
The goal is to write therecursiveFunction(root, arr[i]), and a hint is that the TreeNode class contains a visited boolean that you are to use to help with this algorithm.
I can't quite seem to figure out how to solve this... Given a key, are you supposed to check to see where it would go in the primary BST, and if the parent has already been visited, then return false?
One way would be to build a new BST from the array, then compare the two trees. Think about how that builds the tree one node at a time.
Now, with a visited flag in every node, we start with all the flags being false, then the logic is:
For each value in the array, look for the node for that value (the target node) in the tree:
If the target node is not found, then answer is no (tree and array have different values).
If the path to the target node steps on any node that has not been visited yet, then answer is no (wrong order).
(optional) If the target node has already been visited, throw IllegalArgumentException (duplicate values in array not allowed).
Mark the target node visited.
Scan the tree (BFS or DFS, doesn't matter), and if you find any unvisited node, then answer is no (tree and array have different values).
If you get here, answer is yes.
I have implemented a Splay Tree class that uses nodes to store data. In this class I have tried to convert the data of nodes into a Singly Linked List. 1,000,000 nodes can be inserted into the splay tree and it works perfectly. Using recursion I get a StackOverFlow error when the tree contains 1,000,000 nodes. However when the tree contains around 15000 nodes it is able to be converted to a linked list without a problem.
Here is the code for my toList Method that is inside the splay tree class
public LinkedList<Node> toList() {
LinkedList<Node> list = new LinkedList<Node>();
Node node = root;
addToList(node, list);
return list;
}
private void addToList(Node node, LinkedList<Node> list) {
if(node != null) {
addToList(node.left, list);
list.add(node);
addToList(node.right, list);
}
}
I used this test class below to test the function of this method
#Test
public void testConversionToLinkedList {
SplayTree<Integer,String> st = new SplayTree<Integer,String>();
for(int i = 0; i < 1000000; i++) {
st.insert(i, Integer.toString(i));
}
assertEquals(1000000, st.size());
LinkedList<Node> list = st.toList();
assertEquals(1000000, list.size());
}
The test passes when the size entered is around 15000, however any number greater than that will show a StackOverFlowError
The error occurs at the line addToList(node.left, list);
This is really weird because when i used the same recursion technique to print the data of the nodes into a txt file, there is no StackOverFlow error and the data prints perfectly.
I have tried to use In Order Traversal, PreOrder and PostOrder but I still receive the same error at 1,000,000 nodes. I do know that it could be doing recursion too deeply and the stack runs out of memory. If that is the case is there any way I can convert a splay tree of nodes into a linked list?
Any idea what could be going wrong? cheers
Your poblem is the recursive algorithm. As you figured out there is a limit in the stack size, which is build when you have recursion.
You can always transform recursion to a loop.
here are some examples for DFS and BFS algorithms using loops: Non recursive Depth first search algorithm
You can increase the stack’s size. To do it you have to pass parameter to the jvm.
The format is -Xss[g|G|m|M|k|K].
For example: java -Xss4m YourTreeProgram
The root issue is that splay trees can have a height equal to their node count, so the recursive algorithms you often see applied to binary trees are risky when applied to splay trees.
The easiest approach is to splay the tree as you go.
Find the tree's minimum node. Simply follow the "left" links from the root all the way until they are null. Splay this node to the root, then add it to your list.
Find its successor. I.e. follow the root's "right" link once, then follow "left" repeatedly until null. Splay that node to the root, then add it to your list.
Repeat step 2 until there is no successor (i.e. the root's "right" link is null).
Finding the minimum and successor nodes are no different from other kinds of trees.
This falls under "a software algorithm" from https://stackoverflow.com/help/on-topic
This is from an interview question http://www.glassdoor.com/Interview/Yelp-Software-Engineering-Intern-Interview-Questions-EI_IE43314.0,4_KO5,32_IP2.htm,
particularly "performance of binary tree if implemented thru array or linkedlist"
How would you go about implementing a binary tree via an array or a linked list?
The way I was taught to do it was by having a linked node type of structure that has two pointers, left and right, that is (from https://courses.cs.washington.edu/courses/cse143/12wi/lectures/02-22/programs/IntTreeNode.java)
public class IntTreeNode {
public int data;
public IntTreeNode left;
public IntTreeNode right;
public IntTreeNode(int data) {
this(data, null, null);
}
public IntTreeNode(int data, IntTreeNode left, IntTreeNode right) {
this.data = data;
this.left = left;
this.right = right;
}
}
And then in the actual binary tree
public class IntTree {
IntTreeNode overallRoot;
public IntTree() {
overallRoot = null;
}
....
}
How would you go about this if you were just using an array or a linked list(one pointer)?
But anyways this is supposed to be a quick fire question. Even if you didn't implement the tree, which you aren't supposed to, how would you analyze the performance of the tree? Doesn't the performance depend on the state of the tree, like if it is a BST? Like for a BST, find would be O(log n) because you're cutting off half the tree each time.
How would you analyze performance based on these two implementations right away?
I'm not sure if I understood correctly, but this is what I thought of.
Basically, you can store the nodes in the tree as elements of an array/list.
For arrays, think of something like this:
public class Node {
public int data;
public int left;
public int right;
...
}
Your tree would be an array of Nodes (Node[] tree), such that the root would be the first element tree[0].
Every element refers to its left and right children as indices in the array.
For example, tree[ tree[0].left ] would be the left child of the root.
A left value of -1 could indicate that the node does not have a left child; similarly for right.
For example, consider the following tree:
5
/ \
2 8
\ / \
3 6 9
Suppose you have initially allocated 10 elements in your array.
Since you have fewer than 10 nodes in the tree, some of them will be null.
Here is what it could look like:
(I am representing each Node as a (data,left,right) tuple)
{ (5,1,2) , (2,-1,4) , (8,5,3) , (9,-1,-1) , (3,-1,-1) , (6,-1,-1) , null , null , null , null }
Thus for the node (8,5,3), you can tell that its left child is the sixth element (node (6,-1,-1)) and its right child is the fourth element (node (9,-1,-1)).
The performance of the insertion/deletion functions could vary depending on your precise implementation.
A similar idea can hold for linked lists (but remember that they do not have random access: finding the i-th element requires traversing the list, element by element).
Hope this helps.
When analyzing algorithms as such, you want to look at what type of binary tree is it (balanced vs. unbalanced), plus the three factors regarding sapce/time complexity:
Insertion
Deletion
Search
Comparing linked list vs. array implementations of binary trees, we see the following:
Linked lists insertions and deletions are much less expensive than when done in arrays (think of array element shifts you have to do to fulfill those two operations.
Linked lists offer flexible size, while arrays do not; you will have to handle array expansion when data does not fit within initial array size.
Arrays offer random access, while linked lists do not; e.g. when dealing with an array implementation of a full or complete binary tree, we can easily compute the indices of any node in the tree.
Having that said, for specific implementations of Binary Search Trees, linked lists are better implementations simply because in a binary search tree, access follows the rules of a binary search tree (root's value is greater than left child and less than right child). Therefore, for insertion/deletion and search, average complexity should be O(log n), provided the tree is balanced. If the binary search tree is not balanced, your complexity becomes O(n) for all operations - this is the worst case scenario.