As the title states. I am trying to create a binary search tree from a general tree that I have created. The code for my general node class is:
Node<E> parent;
E data;
ArrayList<Node<E>> children = new ArrayList<Node<E>>();
public Node(E data){
this.data = data;
}
public ArrayList<Node<E>> getChildren(){
return this.children;
}
public void addChild(Node child){
int counter = 0;
for (int i = 0; i < children.size(); i++){
if (child.toString().equals(children.get(i).toString())){
System.out.println("already exists");
counter++;
}
}
if (counter > 0){}
else{
children.add(child);
}
}
public void removeChild(Node<E> child){
children.remove(child);
}
public Node<E> getChild(Node<E> child){
for (int i = 0; i < children.size(); i++){
if (children.get(i) == child){
return child;
}
}
return null;
}
public void setParent(Node parent){
this.parent = parent;
}
public Node<E> getParent(){
return this.parent;
}
public boolean isDirectory(Node node){
if (data == node.data){
return false;
}
return true;
}
public boolean hasChildren(){
return getChildren() != null;
}
public E getData(){
return this.data;
}
public String toString(){
return data.toString();
}
}//end class
And my tree class is full of methods to the brim, so to save all you guys the eye strain, my tree class consists of a root and the constructor which sets the root as the root of the tree. I know that to convert the general tree to the binary search tree, i must set my general tree root to the root of the binary search tree. My question is then where do i go from there? How do i traverse my general tree to add the nodes to the binary search tree? Any help would be appreciated.
A general tree is not binary because it may have arbitrary number of child nodes and is not search because its nodes do not have any specific order. As a consequence constructing a binary search tree from a general tree is just the same as inserting all the nodes of the general tree in the binary search tree. Please note I would not call this convert it is more constructing a binary search tree from the nodes in a general tree.
Related
I have a simple Node class to construct a tree node in my binary tree:
class Node {
int data;
Node left;
Node right;
public Node(int i) {
this.data = i;
}
}
I've written a simple Tree class which will use the Node structure to build a tree:
class Tree {
Node root;
}
I'm trying to write a recursive function mirror() in my Tree class that will return a mirrored version of the tree (left and right nodes swapped).
So if I call this function on a Tree t, I would expect to start from the root, and swap all of the nodes until we reach a node that has no more children to swap. The part I'm struggling with is after we've swapped the root nodes children, how I can recursively call the mirror function on these nodes and then return the mirrored tree.
As you can see, the code below will swap the root node's children, but after that I am stuck as I can't call the mirror function on nodes, only a tree.
public Tree mirror() {
Node temp = this.root.left;
this.root.left = this.root.right;
this.root.right = temp;
If you could point me in the right direction I'd appreciate it.
You need a separate method that will accept Node object, mirror its children and call itself recursively.
public Tree mirror() {
mirrorInternal(this.root);
return this;
}
private void mirrorInternal(Node node) {
Node tmp = node.left;
node.left = node.right;
node.right = tmp;
if (node.left != null) {
mirrorInternal(node.left);
}
if (node.right != null) {
mirrorInternal(node.right);
}
}
I guess you could also change your Node-class such that it uses a flag for mirrored behavior:
class Node {
int data;
Node[] children;
public Node(int i) {
this.data = i;
this.children = new Node[2];
}
public void setLeft(Node node) {
children[0] = node;
}
public void setRight(Node node) {
children[1] = node;
}
public Node getLeft(boolean mirrored) {
return mirrored ? children[1] : children[0];
}
public Node getRight(boolean mirrored) {
return mirrored ? children[0] : children[1];
}
}
void mirror (Tree tree) {
mirror (tree.root);
}
Node mirror (Node node) {
if (node != null) {
Node temp = node.left;
node.left = mirror (node.right);
node.right = mirror (temp);
}
return node;
}
I have TreeNode class - implementation of the node of the non-binary tree (List<TreeNode> children).
I need find the first node with the given data among the children of this. I wrote some method, but there is some problem obviously (java.lang.AssertionError: Failed to find a child with not-null data: expected:<2> but was:<null>). (if data is null I need to return first child with null data).
public TreeNode findChild(Object data) {
if (data == null) {
Iterator<TreeNode> a = getChildrenIterator();
TreeNode tmp;
while (a.hasNext()) {
tmp = a.next();
if (tmp.getData()==null) return tmp;
tmp.findChild(data);
}
}else
{
Iterator<TreeNode> a = getChildrenIterator();
TreeNode tmp;
while (a.hasNext()) {
tmp = a.next();
if (data.equals(tmp.getData())) return tmp;
tmp.findChild(data);
}
}
return null;
}
Your recursion isn't correct. You should be returning the result of tmp.findChild() if it returns a non-null value.
You also need to consider whether you're supposed to be implementing a depth-first or breadth-first search.
The problem is within the fact you don't return the result of the recursive call.
Maybe the following code will help:
import java.util.*;
public class TreeNode
{
// Constructor
public TreeNode()
{
children = new ArrayList<TreeNode>();
node_data = null;
}
// Get node's data
public Object getData()
{
return (node_data);
}
// Set node's data
public void setData(Object data)
{
node_data = data;
}
// Find the node with specified data
// Return null if not found
public TreeNode findChild(Object data)
{
// Maybe we're the one we're looking for
if (equalData(data))
return (this);
// Search within child nodes
Iterator<TreeNode> it;
TreeNode node;
it = getChildrenIterator();
while (it.hasNext())
{
node = findChild(it.next());
if (node != null)
return (node);
}
// If we get here, we didn't find it
return (null);
} // findChild
// Return whether specified data equals ours
private boolean equalData(Object data)
{
if (node_data == null)
return (data == null);
else
return (node_data.equals(data));
}
// Return iterator over node's children
private Iterator<TreeNode> getChildrenIterator()
{
return (children.iterator());
}
// The node's children
private List<TreeNode> children;
// The node's data
private Object node_data;
} // class TreeNode
I am trying to write a binary tree and the add method is continually overwriting the root of the tree. I have two methods a recursive add method that takes in a String and a Node and then a regular add method that simply calls the recursive method. Any help would be greatly appreciated.
public Node recAdd(String event , Node tNode ){
//tNode -> tree node
if (tNode == null){
// Addition place found
root = new Node(event);
System.out.println("added root");
}
else if (tNode.event.compareTo(event) <= 0){
tNode.setLeft(recAdd(event, tNode.getLeft()));
// System.out.println("added left");// Add in left subtree
}
else{
tNode.setRight(recAdd(event, tNode.getRight()));
// System.out.println("added right");
}// Add in right subtree
return tNode;
}
//////////////////////////////////////////////
public void add(String event){
if(root != null){
System.out.println("The root currently is " + root.event );
}
recAdd(event , root);
}
And my node class is as follows
public class Node {
Node left;
Node right;
String event;
Node(String event){
this.event = event;
this.left = null;
this.right = null;
}
public void setEvent(String event){
this.event = event;
}
public void setLeft(Node left){
this.left = left;
}
public void setRight(Node right){
this.right = right;
}
public String getEvent(){
return event;
}
public Node getLeft(){
return left;
}
public Node getRight(){
return right;
}
}
You are replacing the root node whenever you find a spot to insert the current node:
public Node recAdd(String event, Node tNode) {
//tNode -> tree node
if (tNode == null) {
// Addition place found
root = new Node(event); // Problem is RIGHT HERE
System.out.println("added root");
}
//...
}
What's happening is that you recursively search through the tree until you reach a node that hasn't been assigned yet (i.e., it is null). At this point, you are overwriting root rather than creating the new node.
For example:
root
/ \
node null <- You want to assign this node, not overwrite root
/ \
null null
To do this:
public Node recAdd(String event , Node tNode ){
if (tNode == null){
tNode = new Node(event); // <--- Don't overwrite root
}
else if (tNode.event.compareTo(event) <= 0){
tNode.setLeft(recAdd(event, tNode.getLeft()));
}
else{
tNode.setRight(recAdd(event, tNode.getRight()));
}
return tNode;
}
You would also need to modify your add() function:
public void add(String event){
root = recAdd(event , root); // <-----Reassign root
}
I think I have to modify one of the traversals. I tried modifying one that print from the smallest to the largest which is this one
private void printTree(BinaryTreeNode t) {
if (t != null) {
printTree(t.llink);
System.out.print(" " + t.info);
printTree(t.rlink);
}
}
But it didn't work. I'm still stuck on what I should try next. This the binary search tree I'm using:
public class BinarySearchTree extends BinaryTree {
//Default constructor.
//Postcondition: root = null;
public BinarySearchTree() {
super();
}
//Copy constructor.
public BinarySearchTree(BinarySearchTree otherTree) {
super(otherTree);
}
public class BinaryTree {
//Definition of the node
protected class BinaryTreeNode {
DataElement info;
BinaryTreeNode llink;
public DataElement getInfo() {
return info;
}
public BinaryTreeNode getLlink() {
return llink;
}
public BinaryTreeNode getRlink() {
return rlink;
}
BinaryTreeNode rlink;
}
protected BinaryTreeNode root;
//Default constructor
//Postcondition: root = null;
public BinaryTree() {
root = null;
}
//Copy constructor
public BinaryTree(BinaryTree otherTree) {
if (otherTree.root == null) //otherTree is empty.
{
root = null;
}
else {
root = copy(otherTree.root);
}
}
public BinaryTreeNode getRoot() {
return root;
}
The code you have posted looks OK for sorting from smallest to largest.
If you want to sort the other way around, then the following code should work:
private void printTree(BinaryTreeNode t) {
if (t != null) {
printTree(t.rlink);
System.out.print(" " + t.info);
printTree(t.llink);
}
}
All you have to do it swap the llink and rlink. To print the tree from largest to smallest, you can use one of the trees traversal methods. for example, the one that suits this case is the Inorder traversal because it prints the tree from smallest to largest in terms of values. All you have to do is the following:
if(t!=null){
printTree(t.rlink);
System.out.print(" " + t.info);
printTree(t.llink);
}
That should print it from largest to smallest.
I created a BST that sets each node to a String value, I was wondering if there is a way to search through the tree but just one value at a time. So say the String in a node was "truck" is there a way to search through the tree and return "t"? This is the code I have for building the tree:
public class BinaryTree {
public Node root;
public BinaryTree tree;
public static int pos;
public static Node[] theArray;
private static class Node {
Node left;
Node right;
String data;
Node(String s) {
left = null;
right = null;
data = s;
}
}
public BinaryTree plantTree(ArrayList<String> dict) {
tree = new BinaryTree();
Collections.shuffle(dict);
for (String s : dict) {
s.toUpperCase();
tree.add(s);
}
return tree;
}
/**
* Creates an empty binary tree
*/
public BinaryTree() {
root = null;
}
public void add(String data) {
root = add(root, data);
}
private Node add(Node node, String data) {
if (node == null) {
node = new Node(data);
} else {
if (data.compareTo(node.data) > 0) {
node.left = add(node.left, data);
} else {
node.right = add(node.right, data);
}
}
return (node);
}
}
Maybe I misunderstood your question, but it sounds like you want something to iterate through the tree. I would use the visitor pattern. (This sounds like homework anyways, so why not use standard patterns. :))
public class Node<T>{
...
public void visitDepthFirst(Visitor<T> v){
v.visit(this);
if (left != null){
left.visitDepthFirst(v);
}
if (right != null){
right.visitDepthFirst(v);
}
}
}
interface Visitor<T>{
public void visit(T t);
}
...
Node<String> root = ...;
root.visitDepthFirst(new Visitor<String>(){
public visit(String val){
if ("truck".equals(val)){
// do something
}
}
});
I'll let you figure out breadth search. Also, your node class would be more usable using generics. And your class structure is a bit confusing. Might I suggest you just use node AS the tree itself. After all, every node in a tree, is a tree itself. (read about the composite pattern)
So it appears that your trying to search through your tree by the first letter only. This will take just as long as returning the entire word. So you still have to use a BST traversal or search algorithem.
So say the String in a node was "truck" is there a way to search
through the tree and return "t"?
Really, I have no idea what this question is about.
If you have a BST then you search it using binary search. That's that.
A binary search returns true if the element is found. You can implement your own BST and not return a boolean but a Char as in t in your question and null if the value is not part of the tree.