I just want you to have a quick look on my AVL-Tree, which I'm programming. I wrote an AVL-Tree and therefore a remove-Method. The problem with this method is that, the other child of the parent of the node (read it please again, sorry that this sounds a bit complicated) which I'm removing, doesn't get printed out, so also gets removed and I dont know why. Here the code:
#Override
public void remove(E value) throws NoSuchElementException {
if(!contains(value)) throw new NoSuchElementException("Doesn't exist!");
else{
root = remove(finds(value).value, root);
}
}
private Node remove(E x, Node t){
if (t==null) {
System.out.println("Sorry but you're mistaken, " + t + " doesn't exist in this tree :)\n");
return null;
}
System.out.println("Remove starts... " + t.value + " and " + x);
if (x.compareTo(t.value) < 0 ) {
t.left = remove(x,t.left);
}
else if (x.compareTo(t.value) > 0) {
t.right = remove(x,t.right);
}
else if(t.left != null) {
t.value = biggest(t.left).value;
remove(t.value, t.left);
}
else
t = (t.left != null) ? t.left : t.right;
return t;
}
AuDTree<Integer> a = new AuDTree<Integer>();
a.insert(7);
a.insert(5);
a.insert(9);
a.insert(4);
a.insert(6);
a.insert(10);
a.insert(8);
a.remove(4);
this is the test. When I remove the "4", the "6" also gets removed. When I remove the "8", the "10" gets removed, and so on. The AVL-Tree looks like this:
7
5 9
4 6 8 10
Thank you in beforehand :)
Related
There's a practice problem that I've been working on that's been confusing me.
Define a function treeLevelOrder which satisfies the following claim:
If Q is a binary search tree of integers, then treeLevelOrder(Q) is the String representation of the contents of Q according to their level in the tree.
We get this tree as an example
9
/ \
5 16
/ \ / \
1 7 12 19
The value of the expression treeLevelOrder(Q) in this case would be
"[9,5,16,1,7,12,19]".
I've seen similar problems, but they don't follow the same format that I'm looking for, wanting to print by level order or as ordered tuples. Here's some sample code I've been working on:
private String treeLevelOrder(Node Q)
{
if (Q.left == null && Q.right == null)
return "[" + Q.datum + "]";
else if (Q.left == null && Q.right != null)
return "[" + Q.datum + ", "+Q.right.datum+"]" + treeLevelOrder(Q.right);
else if (Q.left !=null && Q.right == null)
return"[" + Q.datum + ", "+Q.left.datum+", *]"+ treeLevelOrder(T.left);
else
return "[" + Q.datum + ", "+Q.left.datum+", "+Q.right.datum+"]" +
treeLevelOrder(Q.left) + treeLevelOrder(Q.right);
}
Any assistance would be helpful.
EDIT: Okay, so I've been experimenting with the level order example at Geeks for Geeks, thank you curlyBraces, that would be closer to what I'm looking for, though I can't figure out to make it return a string. Here's the code they use:
/* function to print level order traversal of tree*/
void printLevelOrder()
{
int h = height(root);
int i;
for (i=1; i<=h; i++)
printGivenLevel(root, i);
}
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(Node root)
{
if (root == null)
return 0;
else
{
/* compute height of each subtree */
int lheight = height(root.left);
int rheight = height(root.right);
/* use the larger one */
if (lheight > rheight)
return(lheight+1);
else return(rheight+1);
}
}
/* Print nodes at the given level */
void printGivenLevel (Node root ,int level)
{
if (root == null)
return;
if (level == 1)
System.out.print(root.data + ", ");
else if (level > 1)
{
printGivenLevel(root.left, level-1);
printGivenLevel(root.right, level-1);
}
}
Any ideas?
Here's an implementation using while loop and two queues to keep track of all the nodes:
public String treeLevelOrder(Node root) {
StringBuilder result = new StringBuilder("");
Queue<Node> current = new LinkedList<>();
Queue<Node> other = new LinkedList<>();
if(root != null)
current.add(root);
while(!current.isEmpty()) {
while(!current.isEmpty()) {
Node node = current.remove();
result.append(",");
result.append(node.datum);
// adding children to the other queue
if(node.left != null)
other.add(node.left);
if(node.right != null)
other.add(node.right);
}
// swapping the queues
Queue<Node> temp = current;
current = other;
other = temp;
}
// building final string
if(result.length() == 0)
result.append("[");
else
result.setCharAt(0,'[');
result.append("]");
return result.toString();
}
So I want my printout of my binary tree to read like [A B C D E F] but I keep ending up with an extra space and I can't use subString to remove it. What is the best way to approach this?
public String toStringInOrder() {
output = "";
output += printInOrder(root);
if(output.length() < 1) {
return "[]";
} else {
return "[" + output.substring(0, output.length() - 1) + "]";
}
}
private String printInOrder(Node current) {
if(current != null) {
printInOrder(current.left);
output += current.value + " ";
printInOrder(current.right);
}
return output;
}
If your only concern is removing the extra space at the end you could replace:
return "[" + output.substring(0, output.length() - 1) + "]";
with:
return "[" + output.Trim() + "]";
Another approach I might take is filling a List with the ordered values, and then you can have a greater control of how you format the ordered values as a string.
If you can't use substring or similars, do a "look for maximum node" search (cheap log(n) operation), save that node and add an if statement on your output additions that checks if the node whose info has to be added isn't the last one. In that case, add the value without the space.
Node last = max(root);
private Node max(Node x){
if (x.right == null)
return x;
return max(x.right);
}
private String printInOrder(Node current) {
if(current != null) {
printInOrder(current.left);
if(!current.equals(last))
output += current.value + " ";
else
output += current.value;
printInOrder(current.right);
}
return output;
}
I discovered the answer I needed after some diagramming and trial and error.
private String printPreOrder(Node current) {
if (current != null) {
output += current.value;
if (current.left != null) output += " ";
printPreOrder(current.left);
if (current.right != null) output += " ";
printPreOrder(current.right);
}
return output;
}
Some changes to the inOrder and postOrder garners similar results. Thanks to all for the help!
I am making a recursive insert method for a binary tree. This method is not able to add nodes to the tree. i cant seem to find whats wrong with this method. the constructor takes a string label for the child and a parent node.
public void insert(String aLabel) {
//if compare is positive add to right else add to left
//basis case:
BSTreeNode aNode = new BSTreeNode(aLabel,null);
if (aNode.parent == null) {
aNode.parent = this;
}
inserts(this,aNode);
}
private void inserts(BSTreeNode aParent, BSTreeNode aNode){
//initially the root node is the parent however a proper parent is found thorough recursion
//left recursion:
if(aParent.getLabel().compareTo(aNode.getLabel()) <= 0) {
if (this.childrenLeft == null) {
this.childrenLeft = aNode;
aNode.parent = this;
return;
} else {
childrenLeft.inserts(childrenLeft, aNode);
}
}
//right recursion
else {
if (this.childrenRight==null) {
this.childrenRight = aNode;
return;
}
else{
childrenRight.inserts(childrenRight,aNode);
}
}
}
EDIT: This answer refers to the original version of the question.
When you call inserts(this.childrenLeft, aNode); you are still at the same node; i.e. this still refers to the old parent.
Instead you should do something like:
childrenLeft.insert(childrenLeft, aNode);
In fact, the first parameter of insert is redundant, you should refactor to remove it.
I think you may need something like this.
The code is commented so you understand what is going on...
// insert method takes The Node as a param and a value to store in BT
public void insert(Node node, int value) {
//Check that the value param is less than the Node (root) value,
// If so insert the data to the left of the root node. Else insert
// the right node as it is a larger number than root
if (value < node.value) {
if (node.left != null) {
insert(node.left, value);
} else {
System.out.println(" Inserted " + value + " to left of "
+ node.value);
node.left = new Node(value);
}
} else if (value > node.value) {
if (node.right != null) {
insert(node.right, value);
} else {
System.out.println(" Inserted " + value + " to right of "
+ node.value);
node.right = new Node(value);
}
}
}
I'm trying to code a binary search tree using java and currently I run into the problem of not being able to retain my value of root after calling certain methods.
Right now I'm writing the add() and height() methods which look like this:
public boolean add(E x) {
BinaryNode<E> temp = null;
if (root == null) {
root = new BinaryNode<>(x);
temp = root;
return true;
} else {
BinaryNode<E> node = root;
if(root.equals(x)){
root = temp;
return false;
}
if (node.element.compareTo(x) < 0) {
if (node.left == null) {
node.left = new BinaryNode<E>(x);
return true;
}
root = node.left;
add(x);
}
if (node.element.compareTo(x) > 0) {
if (node.right == null) {
node.right = new BinaryNode<E>(x);
return true;
}
root = node.right;
add(x);
}
root = temp;
}
return false;
}
A node is described by the following class:
static class BinaryNode<E> {
E element;
BinaryNode<E> left;
BinaryNode<E> right;
private BinaryNode(E element) {
this.element = element;
}
}
Now, I have BinaryNode root; as an attribute in my BST class. The purpose of this attribute is that it allows me to have methods without input parameters by recursively altering the value of root (for educational purposes only, I will not cheat here and use input parameters even though it might be easier).
The add(E x) method seems to be working properly but the problem is that the method height() also alters the attribute root, so when I use add(E x) after calling height() it doesn't work since I've yet to figure out how to retain the value of root through the height() method.
height() currently looks like this:
public int height() {
if(root == null){
return 0;
} else {
int lefth = 0;
int righth = 0;
BinaryNode<E> node = root;
if(root.left != null){
root = root.left;
lefth = height();
}
if(root.right != null){
root = root.right;
righth = height();
}
root = node;
if(lefth > righth){
return lefth+1;
} else {
return righth+1;
}
}
}
I know for sure that this method is faulty since it recursively changes the value of root (which is intended) but it fails in "resetting" the value of root to the actual root of the whole tree, if you know what I mean.
Inside my main method I wrote a couple lines of code to test if the two methods work and I'm quite sure that the add(E x) method works but the height() certainly doesn't work correctly. The purpose of height() is of course to return the height of the tree.
My main method has this:
public static void main(String[] args) {
BinarySearchTree<Integer> tree = new BinarySearchTree<>();
int a = 10;
int b = 11;
int c = 9;
int d = 9;
int e = 5;
int f = 8;
System.out.println("Adding " + a + " " + tree.add(a) + " \tHeight: " + tree.height());
System.out.println("Adding " + b + " " + tree.add(b) + " \tHeight: " + tree.height());
System.out.println("Adding " + c + " " + tree.add(c) + " \tHeight: " + tree.height());
System.out.println("Adding " + d + " " + tree.add(d) + " \tHeight: " + tree.height());
System.out.println("Adding " + e + " " + tree.add(e) + " \tHeight: " + tree.height());
System.out.println("Adding " + f + " " + tree.add(f) + " \tHeight: " + tree.height());
}
And it outputs the following lines into to console:
Adding 10 true Height: 1
Adding 11 true Height: 2
Adding 9 true Height: 2
Adding 9 false Height: 0
Adding 5 true Height: 1
Adding 8 true Height: 2
So, as it seems, my add(E x) is functioning properly since I'm not allowed to add duplicates. However I really don't know how to code height() correctly.
Any help would be greatly appreciated!
I've not gone through the code in detail but it looks/sounds like you are mixing temporary/local variables and class ones.
You are modifying the root node when you call height and this actually changes the globally scored one.
What you should instead do is have a local variable within the method that stores the current root and uses that to search, rather than modifying the global one.
i.e.
public int height() {
Node searchNode = root;
if(searchNode == null){
Now you do all the processing using searchNode without corrupting the global record of the root node.
I have binary tree that is keeping variables and lines they appear on from a .txt file. I previously had put the creation of new nodes mistakenly in the method to check if its contained, which created an abundance of nodes. At that point it printed the correct information but then exited with an error. I realized this and moved it to the insert method, but now print gives me just an error and no results. I have been struggling with this for awhile now and I can't figure out what is wrong with it. Any help would be appreciated greatly.
My code for those 2 methods is:
public void insert(String inputVar, int line, BinaryNode t)
{
if (t.var == null)
{
t.var = inputVar;
t.lines[t.count] = line;
t.count++;
}
else if (inputVar.compareTo(t.var) < 0)
{
if (t.left == null)
t.left = new BinaryNode(100);
insert(inputVar, line, t.left);
}
else if (inputVar.compareTo(t.var) > 0)
{
if (t.right == null)
t.right = new BinaryNode(100);
insert(inputVar, line, t.right);
}
}
public void printTree(BinaryNode t)
{
if (t.var == null)
{
}
else if (t.left == null && t.right !=null)
{
System.out.printf("The variable %s appears at lines ", t.var);
for (int l = 0; l < t.count; l++)
{
System.out.printf("%d ", t.lines[l]);
}
System.out.println();
printTree(t.right);
}
else if (t.right == null && t.left != null)
{
printTree(t.left);
System.out.printf("The variable %s appears at lines ", t.var);
for (int l = 0; l < t.count; l++)
{
System.out.printf("%d ", t.lines[l]);
}
System.out.println();
}
else
{
printTree(t.left);
System.out.printf("The variable %s appears at lines ", t.var);
for (int l = 0; l < t.count; l++)
{
System.out.printf("%d ", t.lines[l]);
}
System.out.println();
printTree(t.right);
}
}
I get an error from the if statement in printTree.
Your base case is t == null, but your code doesn't handle that case. That is, an empty tree is not a node with no variable, but a null node.
Why must your print method be so complicated anyway?
public void printTree( BinaryNode t ) {
if ( null == t )
return;
printTree( t.left );
System.out.printf( "The variable %s appears at lines ", t.var );
for ( int l = 0; l < t.count; l++ )
System.out.printf( "%d ", t.lines[ l ] );
System.out.println();
printTree( t.right );
}
You may reach the last case (else in printTree() ) when both t.right == null && t.left == null so you make a recursive call with both (null) childs and then fall on a NPE in the first check if(t.var == null) where t is null