I want to check if a binary search tree is degenerate or not (Is it a linked list or indeed a tree?) I've been trying for a while and have come up with nothing that works. I did come up with a nonrecursive solution which I thought was quite clever but the specifications state it has to be a recursive solution and I'm having translating it from non-recursive to recursive.
Here's my non-recursive solution (well not really because size and height are both implemented recursively. This method however is not).
public boolean isDegenerate(){
if(this.size() == this.getHeight()){
return true;
}
return false;
}
Well, if you want a "more recursive" solution, how about this?
public boolean isDegenerate() {
if (this.left != null) {
if (this.right != null) {
return false; // not degenerate, has two children
} else {
return this.left.isDegenerate();
}
} else {
if (this.right != null) {
return this.right.isDegenerate();
} else {
return true; // we arrived at the bottom without seeing any node with two children
}
}
}
Related
I'm trying to write a recursive code to check if a binary search tree is valid using an in-order traversal but without using an array. In other words, using only a previous value. I'm trying to keep the previous value as a parameter, but the code is failing. I've trie debugging but not sure why the code is not working.
class Solution {
public boolean isValidBST(TreeNode root) {
return isValidBSTPrev(root, null);
}
public boolean isValidBSTPrev(TreeNode root, TreeNode prev) {
if(root == null) {
return true;
} else if(isValidBSTPrev(root.left, root)
&& (prev!=null && root.val > prev.val)
&& isValidBSTPrev(root.right, root)) {
return true;
} else {
return false;
}
}
}
I am working on a programming assignment that requires us to write a path(root, value) method that returns a LinkedList of Direction Enums (left, right) that leads to the target node (value). We are not allowed to create any new fields to make this happen, which is why I've created a pathHelper() method. One of the tests I'm failing is supposed to return: left, right as the path but it's returning left, right, left, right. I'm not sure why it's counting the steps twice. Any suggestions would be appreciated!
NOTE: This is a Binary Tree, not a BST. We are supposed to use an exhaustive DFS approach.
public static <T> LinkedList<BinaryNode.Direction> path(BinaryNode<T> root, T value) {
if (root == null) {
return null;
} else if (root.payload == value) {
return new LinkedList<>();
}
LinkedList<BinaryNode.Direction> list = new LinkedList<>();
pathHelper(root, value, list);
return list;
}
public static <T> void pathHelper(BinaryNode<T> root, T value, LinkedList<BinaryNode.Direction> list) {
if (root.left != null) {
if (root.payload != value) {
list.add(BinaryNode.Direction.left);
}
pathHelper(root.left, value, list);
} if (root.right != null) {
if (root.payload != value) {
list.add(BinaryNode.Direction.right);
}
pathHelper(root.right, value, list);
}
}
Your code has quite a few errors in it so I'm surprised any test cases are passing. You seem to be storing directions as you search the tree rather than when you find the value.
I suspect you are overcomplicating the problem. If you return a boolean from your helper function based on whether the item is found then you can easily add the directions when you return from the recursion:
private boolean findPath(BinaryNode<T> node, T value, List<BinaryNode.Direction> directions) {
if (node == null) {
return false;
} else if (node.payload.equals(value)) {
return true;
} else if (findPath(node.left, value, directions)) {
directions.add(0, BinaryNode.Direction.LEFT);
return true;
} else if (findPath(node.right, value, directions)) {
directions.add(0, BinaryNode.Direction.RIGHT);
return true;
} else {
return false;
}
}
Note that this inserts the direction at the start of the list to ensure it's in the correct order. This also allows you to detect where the root has the value because it will return true but the path will be empty.
I am implementing different methods in a binary search tree and am stuck on the insert method as it just doesn't seem to work.
I have been trying to implement the insert method for a while now but nothing seems to work it's always returning null. This method takes a user and adds it to the database. Using the User class.
public boolean beFriend(User friend) throws IllegalArgumentException {
User node = friend;
if (friend == null) {
throw new IllegalArgumentException();
}
if(root == friend) {
return false;
} else if(root.getKey() < friend.getKey()) {
if(root.getLeft() != null) {
root.setLeft(friend);
return true;
} else {
root.setLeft(node);
return true;
}
} else { if(root.getRight() != null) {
root.setRight(friend);
} else {
root.setRight(node);
return true;
}
}
return false;
}
I expect the User friend to be added to the database and output its details but the output that I am currently getting is null.
You don't define "root" in your method, therefore it's always null. You should define "root" to compare with friend and getting any data from it.
I'm recursively adding nodes to my avl tree and I'm an efficiency FIEND! Therefore, when I'm adding data called d1 and I get all the way down to a node that already has d1, I won't add it, and so I need to know how to avoid updating on the way back up the recursive "stack," as I like to think of it. If there's a way to trigger something that destroys all recursive calls that'd be splendid.
I haven't tried too much because I can't really think of a way around it.
private void rAdd(AVLNode<T> rootTemp, T data) {
if (rootTemp.getData().compareTo(data) > 0) {
if (rootTemp.getLeft() == null) {
rootTemp.setleft(data);
rootTemp.getLeft().setLeft(null);
rootTemp.getLeft().setRight(null);
rootTemp.getLeft().setHeight(0);
rootTemp.getLeft().setBalanceFactor(0);
return;
} else {
if (rootTemp.getLeft().getData().compareTo(data) == 0) {
return;
} else {
rAdd(rootTemp.getLeft(), data);
update(rootTemp);
}
}
} else {
if (rootTemp.getRight() == null) {
rootTemp.setleft(data);
rootTemp.getLeft().setLeft(null);
rootTemp.getLeft().setRight(null);
rootTemp.getLeft().setHeight(0);
rootTemp.getLeft().setBalanceFactor(0);
return;
} else {
if (rootTemp.getRight().getData().compareTo(data) == 0) {
return;
} else {
rAdd(rootTemp.getRight(), data);
update(rootTemp);
}
}
}
}
I need this bad boy to be efficient and without any crazy imports like I see a bunch of people recommend.
trying to write a boolean method that tells if someone is a decendant of someone...but can't seem to do it. of course, the object is a descendant if it's a child...or the descendant of a child.
public boolean isDescendant(member x){
if (children.contains(x)){
return true;
}
else{
return false;
}
}
but where or how do i insert:
for (int i = 0; i < children.size(); i++){
isDescendant(children.get(i));
}
thanks!
I think what you want is below:
// Cleaned up version
public boolean isDescendant(member x){
// check for direct descendance
if (children.contains(x)){
return true;
}
// check for being descendant of the children
for (Child c: children){
if (children.get(i).isDescendant(x)) {
return true;
}
}
return false;
}
Walking trees is very slow downwards (from the root to the leaves). Consider this implementation for the is-ancestor check:
/**
* Checks whether the given node is an ancestor of this node.
*/
public boolean isDescendantOf(Node ancestor) {
Preconditions.checkNotNull(ancestor, "Ancestor");
if (equals(ancestor)) {
// every node is an ancestor to itself
return true;
} else if (parent == null) {
// not related
return false;
} else {
// recursive call
return parent.isDescendantOf(ancestor);
}
}
The other way is now a piece of cake.
public boolean isDescendant(Node descendant) {
return descendant.isDescendantOf(this);
}
No loops, no exponentional effort.
PS:
In my example i would suggest renaming isDescendant to isAncestorOf.
public boolean isDescendant(member currentRoot, member x){
//check the current level
if (currentRoot.children().contains(x)){
return true;
}
//leaf
if( currentRoot.children().isEmpty() ){ return false; }
//try all my children
boolean found = false;
for( Member child : currentRoot.children() ){
found = isDescendant( child, x );
if( found ) break;
}
return found;
}
You need to recurse over the current root, most likely.
Edit: If your data structure has parent pointers, use these instead of searching your descendants in the tree. If not, consider adding them. See the answer from whiskeysierra for a solution with parent pointers. Only if adding them is not possible, consider this answer.
The current answers all have two loops through children (one in children.contains(), one later).
This variant may be a bit more efficient (but it does not change the O-class), and is a bit shorter. (If children is a set with fast contains-check (like HashSet) and often the hierarchy is not so deep (so you don't need to recurse at all), the other answers are better.)
public boolean isDescendant(Member x) {
for(Member child : children) {
if(child.equals(x) || child.isDescendant(x))
return true;
}
return false;
}
If a node is considered a descendant of itself, you can write it like this:
public boolean isDescendant(Member x) {
if(equals(x))
return true;
for(Member child : children) {
if(child.isDescendant(x))
return true;
}
return false;
}