I try to implement a splay tree by java. The code.
Ordinary, binary search tree's print:
public void printTree(BinaryNode<AnyType> node){
if(node != null){
printTree(node.left);
System.out.println(node.element);
printTree(node.right);
}
But print each node should invok splay() method, and right child tree and left child tree of node will transform.
Related
I have a method for finding the next inorder successor within a Binary Search Tree (BST). The "inorderSuccessor" method takes any node of the BST as input and output the next inorder successor. The method and tree class are defined as follow:
class BSTInorderSuccessor{
public static Node inorderSuccessor(Node node) {
if (node.right != null) {
return minValue(node.right);
}
Node parent = node.parent;
while (parent != null && node == parent.right){
node = parent;
parent = parent.parent;
}
return parent;
}
}
class TreeNode{
int data;
Node left;
Node right;
Node parent;
public TreeNode(int data){
this.data = data;
this.left = null;
this.right = null;
this.parent = null;
}
}
Suppose the height of the BST is h, and there are n nodes within this tree structure. I know that the time complexity of "inorderSuccessor" method is O(h).
My question is: Given the smallest node of the BST. When I write a method to continuously call "inorderSuccessor" to print all the nodes of the BST, what is the total time complexity? I think it is O(n * h). Is that correct?
You can upper-bound the cost of printing everything out by always finding the inorder successor at O(nh), but that's actually not a tight bound. You can show that the runtime is actually Θ(n), independently of the height of the tree!
One way to see this is to look at how many times each edge in the tree gets visited. If you trace out the execution of all those inorder traversals, you'll find that you go down each edge exactly once and go up each edge exactly once, and the total work done is proportional to the number of times each edge is visited. The number of edges in an n-node tree is Θ(n), hence the runtime bound.
Note that you can't say that each individual operation will take time O(1). That's not true. What you can say is that in aggregate each one takes an average of O(1) time.
So I know for a binary tree the general way to preorder traverse it is like this
void displayPreOrder(TreeNode node)
{
if(node != null)
{
displayPreorder(node.left);
displayPreorder(node.right);
System.out.println(node.value);
}
}
But I'm having trouble trying to wrap my head around a preorder traversal of a quadtree. I've tried to find some resources, but left empty handed. Any hint?
The code you posted is for a postorder traversal of a binary tree. For a quadtree, you just need to visit all children instead of just left and right.
For simplicity, I'll assume that TreeNode defines a method children() that returns an iterator or a List of the node's children in some well-defined order. If that's not available, just iterate through the children using whatever mechanism is available.
void displayPreOrder(TreeNode node)
{
if(node != null)
{
// visit the root first for pre-order
System.out.println(node.value);
for (TreeNode child : node.children()) {
displayPreorder(child)
}
}
}
(P.S. This works for binary trees as well, given the right iteration mechanism.)
So I'm trying to put an element in a binary tree (not a search tree) in java. I looked everywhere, and all I can see are algorithms for inserting it into a binary search tree (and I want a simple binary tree). Given the value of the parent node, I need to set the left and right children. My plan looks like this:
public void addLeft(E elem, E parentVal) {
//Find node with parentVal
//Create node with element elem (call it newNode)
//Set the left child of the node with parentVal as newNode
}
The last 2 steps are fairly simple, so my real problem is finding the node with a given value.
In a search tree, it is an easy task, but in a normal binary tree, I don't know how to do it. I understand that it won't be efficient; as far as I know, to add an element to a given node in a normal binary tree, we have to traverse the entire tree to find that node. Any suggestions on how to do this? Assume there will be no repeats of numbers (all nodes have a unique element). I've tagged this as algorithm/pseudocode, so just a basic idea is all I need to get started (although code is appreciated as well).
Here is a simple way of recursively traversing the tree and stopping when parentVal is found:
// returns true if the element has been added to this subtree
public boolean addLeft(E elem, E parentVal) {
if (this.equals(parentVal)) {
//Create node with element elem (call it newNode)
//Set the left child of the node with parentVal as newNode
return true;
} else if (leftChild != null && leftChild.addLeft(elem, parentVal)) {
return true;
} else {
return rightChild != null && rightChild.addLeft(elem, parentVal);
}
}
This is assuming that a node has access to its children through leftChild / rightChild.
Found this in Google code and in github search took me to this Java implementation
Another quick raw write-up implementation is the python implementation of Binary tree. The heading for link is misleading, but check the entire write-up.
From the link here is a high level psuedo.,
class Node:
...
def insert(self, data):
"""
Insert new node with data
#param data node data object to insert
"""
if data < self.data:
if self.left is None:
self.left = Node(data)
else:
self.left.insert(data)
else:
if self.right is None:
self.right = Node(data)
else:
self.right.insert(data)
I am hopelessly lost when it comes to recursive functions. I am required to create a recursive function to traverse a binary tree and insert a new node in between specific values. Would i need to recopy my traverse function and modify it in every other function that i use it in? Would someone please evaluate the traverse function?
I think my traversing code is alright.
Node traverse (Node currentNode){
if (!currentNode.left.equals(null)){
traverse (currentNode.left);
return currentNode.left;
}
if (!currentNode.right.equals(null)){
traverse (currentNode.right);
return currentNode.right;
}
return currentNode;
}
When it comes to binary trees, there are several different types of traversals that can be done recursively. They're written in the order they're referenced then visited (L=Left child, V = visit that node, R = right child).
In-order traversal (LVR)
Reverse order traversal (RVL)
Preorder traversal (VLR)
Postorder traversal (LRV)
Your code appears to be performing the postorder traversal method, but you're getting a few things mixed up. First, the node is what you want to traverse; the data is what you want to visit. Second, you have no reason to return the node itself, in the way that this is implemented. Your code doesn't allow for a condition to say, 'I'm looking for this particular data, do you have it Mr. Node#0xdeadbeef?', which would be found with some sort of extra search parameter.
An academic BST traversal only prints the nodes itself. If you wanted to add a search functionality, it's only one more parameter, as well as an additional check for the right node.
Here's a snippet:
// Academic
public void traverse (Node root){ // Each child of a tree is a root of its subtree.
if (root.left != null){
traverse (root.left);
}
System.out.println(root.data);
if (root.right != null){
traverse (root.right);
}
}
// Search with a valid node returned, assuming int
public Node traverse (Node root, int data){ // What data are you looking for again?
if(root.data == data) {
return root;
}
if (root.left != null && data < root.data) {
return traverse (root.left, data);
}
if (root.right != null && data > root.data) {
return traverse (root.right, data);
}
return null;
}
It seems like you are traversing in the preorder methodology, but i am a little skeptical as to what exactly you wish to accomplish without actually comparing your current node with some base value that defines u have reached ur destination. I would suggest drawing out a simple tree and visualizing the steps. Then try to put that into code.
A recursive function returns the value of itself with a modified parameter, or a termination (exit) condition. eg, Factorial:
int factorial( int param ) {
if ( param > 1 ) {
return param * factorial( param -1 );
} else {
return 1;
}
}
In your code, you call a 'traverse' but then do nothing with the result...
When your recursive function ends, your final return will be first left child if it exists, else the first right child if it exists, else the root node.
Please give more detail as to why you need to traverse the tree (also, not sure what you meant by "copy the function and modify it in every other function", the whole idea of a function is to code-once-call-many)
Okay. I have a binary tree, and this is what I want to do with it:
For each node in original tree:
If it's not a leaf, replace it with a leaf node.
Do a calculation on the original tree updated with the removed branch.
Revert the node back to how it was (so now the tree is the same as at the beginning).
The problem is this: I am traversing the tree using a stack. If I change the stack.pop() node to a leaf, this does NOT remove any branches in the original tree. It's the same reasoning behind why you can do:
int x=1
int y=x
y++
And x still equals 1. There's a technical term for this but I forgot it.
So how can I edit the nodes in an original tree and still traverse it?
This is basically what I'm doing to traverse the tree right now:
public void iterativePreorder(Node root) {
Stack nodes = new Stack();
nodes.push(root);
Node currentNode;
while (!nodes.isEmpty()) {
currentNode = nodes.pop();
Node right = currentNode.right();
if (right != null) {
nodes.push(right);
}
Node left = currentNode.left();
if (left != null) {
nodes.push(left);
}
//This is where you do operations on the currentNode
}
}
From what I can tell from your question, for every Node you want to calculate something about the tree as if that node was a leaf.
To do this there is no reason to actually make that node a leaf and then reattach it. Instead, your logic can simply remember which node to treat as a leaf for each computation.
Traverse the tree, and for each Node, let's call it outerCurrentNode, once again traverse the tree doing your calculation - but now for each Node, let's call it innerCurrentNode, test to see if outerCurrentNode == innerCurrentNode. If the test returns true, treat that innerCurrentNode as if it's a leaf, ignoring its children.
EDIT: Here's a mock up of what I'm suggesting (untested):
//entry point - called from directing code
public void iterativePreorder(Node root) {
iterativePreorderKernel(root, root);
}
//recursive method - keeps track of root in addition to current Node
private void iterativePreorderKernel(Node root, Node current) {
if (current.left() != null) {
iterativePreorderKernel(root, current.left());
}
if (current.right() != null) {
iterativePreorderKernel(root, current.right());
}
//for each Node in the tree, do calculations on the entire tree, pretending
//the current Node is a leaf
doCalculation(root, current);
}
//calculation method (also recursive) - takes a current Node, plus
//the Node to treat as a leaf
public void doCalculation(Node innerCurrent, Node pretendLeaf) {
//do calculation with inner current node
if (innerCurrent != pretendLeaf) {
if (innerCurrent.left() != null) {
doCalculation(innerCurrent.left(), pretendLeaf);
}
if (innerCurrent.right() != null) {
doCalculation(innerCurrent.right(), pretendLeaf);
}
}
}
I'm using recursion instead of a Stack, but either will work. iterativePreorder() does a traversal, calling doCalculation() for each Node, passing it in along with the root (to keep track of the entire tree). That method then does its own traversal, doing your calculation, but stopping short when it reaches the specially marked Node.