My Question:
I have a Java program that searches for the Lowest Common Ancestor in a Binary Tree. That part should work, but my question is regarding my main method so I haven't properly tested it. I need to create a binary tree from the chars stored in my array.
What I've found
To put it simply, not much. I've found a few pages that touch on the subject, but their implementations seem so vastly different from the rest of my code. If someone can even provide links to a guide, preferably with code examples, that could possibly answer my question.
My Code
public class TreeMain
{
static TreeNode root;
public static void main(String args[])
{
String[] myStringsChars = new String[26];
for(int i = 0; i < 26; i++)
{
myStringChars[i] = new String(Character.toChars(i+65));
System.out.println(myStringChars[i]);
}
// array to binary tree
TreeNode commonAncestor = findLowestCommonAncestor(firstNode, secondNode);
if(commonAncestor != null) {
System.out.println(commonAncestor.getContents()); }
}
public static TreeNode findLowestCommonAncestor(TreeNode node1, TreeNode node2)
{
return findLCA(root, node1, node2);
}
public static TreeNode findLCA(TreeNode node, TreeNode node1, TreeNode node2)
{
if (node == null) {
return null; }
if (node.getContents() == node1 || node.getContents() == node2) {
return node; }
TreeNode leftLCA = findLCA(node.getLeftChild(), node1, node2);
TreeNode rightLCA = findLCA(node.getRightChild(), node1, node2);
if (leftLCA!=null && rightLCA!=null)
return node;
// Otherwise check if left subtree or right subtree is LCA
return (leftLCA != null) ? leftLCA : rightLCA;
}
}
public class TreeNode<T extends Comparable>{
private T contents;
private TreeNode<T> parent;
private TreeNode<T> leftChild;
private TreeNode<T> rightChild;
private int level;
public TreeNode(T data, TreeNode parent)
{
contents = data;
this.parent = parent;
}
public void setLeftChild(TreeNode node)
{
this.leftChild = node;
}
public void setRightChild(TreeNode node)
{
this.rightChild = node;
}
public boolean isContentEquals(T data)
{
return 0 == getContents().compareTo(data);
}
public T getContents() {
return contents;
}
public void setContents(T contents) {
this.contents = contents;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getLeftChild() {
return leftChild;
}
public TreeNode getRightChild() {
return rightChild;
}
public TreeNode findNodeOnTree(T contentToSearch)
{
List<TreeNode> nodes = new LinkedList();
nodes.clear();
nodes.add(this);
while(!nodes.isEmpty())
{
TreeNode current = nodes.remove(0);
if(current.isContentEquals(contentToSearch))
{
return current;
}
if(current.leftChild != null)
{
nodes.add(current.leftChild);
}
if(current.rightChild != null)
{
nodes.add(current.rightChild);
}
}
return null;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
I haven't tried your algorithm yet, but the part you are looking for should be pretty straightforward. One quick way to achieve it would be to draw the picture of the binary tree you have in mind and just write a couple of methods to translate that picture to code. Here's what I'd start with:
public TreeNode<T> addLeft(T key) {
TreeNode<T> tmp = new Node<>(key);
this.left = tmp;
tmp.parent = this; // if you are using parent pointers
return tmp; // for chaining purpose, so returned node can be subject to addition
}
public TreeNode<T> addRight(T key) {
TreeNode<T> tmp = new TreeNode<>(key);
this.right = tmp;
tmp.parent = this;
return tmp;
}
To construct the tree, you can create a root node and then call the addLeft() and addRight() methods as you see in the picture of your binary tree:
TreeNode<Character> root = ...; // say root's key is 'A'
TreeNode<Character> left1 = root.addLeft('B');
TreeNode<Character> right1 = root.addRight('C');
//TreeNode<Character> left2 = left1.addLeft();
// and so on for your character array.
A more involved way is to think of the inorder traversal and preorder traversal of the tree that you have in mind, represent the two traversals as two separate arrays and then write another procedure to accept these two arrays that constructs a binary tree out of this. This is left as an exercise.
Related
Have a recursive remove function for BST that isn't zeroing a pointer to a leaf node.
bool removeNode(Node* tree, int key)
{
bool removed = false;
if (tree)
{
if (key < tree->key)
{
removeNode(tree->left, key);
}
else if (key > tree->key)
{
removeNode(tree->right, key);
}
else // this node is the key
{
if (!tree->left && !tree->right) // leaf
{
free(tree);
tree = 0;
}
else if (!tree->left)
{
*tree = *tree->right;
}
else if (!tree->right)
{
*tree = *tree->left;
}
else // this node has 2 children
{
Node* paux = tree->left;
if (paux->right)
{
while (paux->right)
{
paux = paux->right;
}
}
tree->key = paux->key;
tree->left = paux->left;
}
removed = true;
}
}
return removed;
}
I use
Node* node = (Node*)malloc(sizeof(Node));
to allocate memory. My leaf's address is correctly zeroed, but when it returns to the previous call, the address remains still the same. If the address was zeroed, why does it return to the previous value? The change should have affected the pointer... shouldn't it?
Data structures and related functions:
typedef struct Node
{
int key;
struct Node* left;
struct Node* right;
} Node;
// init a binary tree
void init(Node** tree, int key)
{
*tree = (Node*) malloc(sizeof(Node));
(*tree)->key = key;
(*tree)->left = 0;
(*tree)->right = 0;
}
// insert at binary tree
bool insert(Node** tree, int key)
{
bool inserted = false;
if (!*tree)
{
init(&*tree, key);
}
else
{
Node* node = (Node*)malloc(sizeof(Node));
node->key = key;
node->left = 0;
node->right = 0;
Node* paux = *tree;
Node* root = paux;
while (paux != 0)
{
root = paux;
if (key < paux->key)
{
paux = paux->left;
}
else
{
paux = paux->right;
}
}
paux = node;
if (key < root->key)
{
root->left = paux;
}
else
{
root->right = paux;
}
inserted = true;
}
return inserted;
}
void print(Node* tree)
{
if (tree != 0)
{
printf("%d ", tree->key);
print(tree->left);
print(tree->right);
}
The problem you encounter happens because the function is not able to modify the input pointer. The pointer itself is passed by value.
Think of a function that increments an integer. The trivial implementation will not work as the argument is passed "by value".
void inc(int x)
{
x++;
}
you can fix this sample by passing it by reference (a pointer)
void inc(int *x)
{
(*x)++;
}
so, if you want to be able to nullify the pointer from within the function pass a pointer to the pointer:
bool removeNode(Node **tree, int key)
As you want to be able to change tree inside the function you need a double pointer.
Instead of
bool removeNode(Node* tree, int key)
you need
bool removeNode(Node** tree, int key)
^^
That also means that you need to change the way you access tree inside the function.
Also see: https://stackoverflow.com/a/39436538/4386427 - it is the same problem
removeNode() has its own copy of tree, so changes to the actual value of tree itself are not visible outside removeNode(). One option is to make tree a Node **, as others have suggested. Another option is to refactor so that you have the parent's pointer available at the point where you want to free the node. For example, the parent could be passed as another parameter to removeNode(), or your code could test one level deeper while processing. Then you could do free(parent->left); parent->left=0; or some such.
I may just be entirely ignorant to what is happening here but i've looked over it a million times and i'm sure it is something obvious but my insert method infinitely loops due to the while loop. Any help would be appreciated.
Here is the code..
package dcjaniszewskiOL4;
public class DoublyLinkedList<T extends Comparable> {
private class Node<T>
{
private T data;
private Node<T> next;
private Node<T> prev;
private Node(T d){
data=d;
next=null;
prev=null;
}
private Node( T d, Node<T> pref, Node<T> nref){
data=d;
prev=pref;
next=nref;
}
}
private Node<T> head;
private Node<T> current;
private int size;
public DoublyLinkedList(){
head = new Node<T>(null,null,null);
current=head.next;
size=0;
}
public DoublyLinkedList(DoublyLinkedList<T> i){
}
public void insert (T d){
Node<T> ptr, trav, prev;
prev=null;
begin();
trav=head.next;
if(empty()){
head.next = new Node<T>(d,head,head);
}
while(trav!=null){
System.out.println(trav.data);
prev=trav;
advance();
trav=current;
}
ptr = new Node<T> (d, prev,head);
if(prev==null){
head.next=ptr;
head.prev=ptr;
}
else{
prev.next=ptr;
current.prev=ptr;
}
size++;
}
public void remove(T d) throws ListEmptyException, NotInListException{
Node<T> tmp = head;
if(head.next==null){
throw new ListEmptyException("List is empty on Remove");
}
while(tmp!=null){
if(tmp.data.equals(d)){
tmp.prev.next=tmp.next;
tmp.next.prev=tmp.prev;
size--;
}else{
tmp=tmp.next;
if(tmp==null){
throw new NotInListException("Item is not in the list");
}
}
}
}
public void begin(){
current=head.next;
}
public void advance(){
current.prev = current;
current=current.next;
}
public void retreat(){
current.next=current;
current=current.prev;
}
public T current() throws ListEmptyException{
if(current==null){
throw new ListEmptyException("List is empty");
}else{
return current.data;
}
}
public boolean end(){
boolean end = false;
if(current==null){
end=true;
}else{
end=false;
}
return end;
}
public boolean empty(){
boolean empty = false;
if(size()==0){
empty=true;
}else{
empty=false;
}
return empty;
}
public int size(){
return size;
}
}
try this
ptr = new Node<T> (d, null,null);
trav=head;
while (trav.next!= null)
{
trav = trav.next;
}
trav.next = ptr;
ptr.prev = trav;
Let me know if it doesn't work
I'm very new to sharepoint and I have to a task with it.
I have my site adress but just about it.
I need to populate a treeview with all the hierarchy from SPSite and down for my sharepoint site using C#;
I guess I need to use recursive functions to do so...
can anyone help?
thank you.
Solved!
public void FillTreeSPWeb(SPWeb MySPWeb, TreeNode Node, int num)
{
if (num <= 0)
{
Node.Text = MySPWeb.Title;
GetSPDocumentLibrary(MySPWeb, Node);
}
num--;
foreach (SPWeb item in MySPWeb.Webs)
{
TreeNode Child = new TreeNode();
FillTreeSPWeb(item, Child,num);
Node.Nodes.Add(Child);
}
}
public void GetSPDocumentLibrary(SPWeb MySPWeb,TreeNode Node)
{
foreach (SPList item1 in MySPWeb.Lists)
{
if (item1.BaseType == SPBaseType.DocumentLibrary)
{
SPDocumentLibrary oDocumentLibrary = (SPDocumentLibrary)item1;
try
{
TreeNode Child = new TreeNode(oDocumentLibrary.Title);
GetFiles(oDocumentLibrary.RootFolder, Child);
foreach (SPListItem item in oDocumentLibrary.Folders)
{
TreeNode GrandChild = new TreeNode();
FillFilesAndFolders(item.Folder, GrandChild);
Child.Nodes.Add(GrandChild);
}
Node.Nodes.Add(Child);
}
catch { }
}
}
}
public void FillFilesAndFolders(SPFolder MySPFolder, TreeNode Node)
{
Node.Text = MySPFolder.Name;
GetFiles(MySPFolder, Node);
foreach (SPFolder item1 in MySPFolder.SubFolders)
{
FillFilesAndFolders(item1, Node);
}
}
public void GetFiles(SPFolder MySPFolder,TreeNode Node)
{
foreach (SPFile item in MySPFolder.Files)
{
Node.Nodes.Add(item.Name);
}
}
I am creating AVL binary tree in which the only problem is that the root is not changes its position or gets balance except all other child's root or leaves etc
Any help would be greatly appreciated!
Logical Layer file
public class Node
{
public int data;
public Node left, right;
public Node(int data)
{
this.data = data;
left = null;
right = null;
}
}
public class BinaryTree
{
public Node root;
public BinaryTree()
{
root = null;
}
public int height(Node temp)
{
int h = 0;
if (temp != null)
{
int l_height = height(temp.left);
int r_height = height(temp.right);
int max_height = Math.Max(l_height, r_height);
h = max_height + 1;
}
return h;
}
public int diff(Node temp)
{
int l_height = height(temp.left);
int r_height = height(temp.right);
int b_factor = l_height - r_height;
return b_factor;
}
Node rr_rotation(Node parent)
{
Node temp;
temp = parent.right;
parent.right = temp.left;
temp.left = parent;
return temp;
}
Node ll_rotation(Node parent)
{
Node temp;
temp = parent.left;
parent.left = temp.right;
temp.right = parent;
return temp;
}
Node lr_rotation(Node parent)
{
Node temp;
temp = parent.left;
parent.left = rr_rotation(temp);
return ll_rotation(parent);
}
Node rl_rotation(Node parent)
{
Node temp;
temp = parent.right;
parent.right = ll_rotation(temp);
return rr_rotation(parent);
}
Node balance(Node temp)
{
int bal_factor = diff(temp);
if (bal_factor > 1)
{
if (diff(temp.left) > 0)
temp = ll_rotation(temp);
else
temp = lr_rotation(temp);
}
else if (bal_factor < -1)
{
if (diff(temp.right) > 0)
temp = rl_rotation(temp);
else
temp = rr_rotation(temp);
}
return temp;
}
public Node addNode(int data) // It only add the Root(that is 55 in the fig)
{
Node newNode = new Node(data);
if (root == null)
{
root = newNode;
}
return root;
}
public Node insertNode(Node root, int newNode) //But I want to make this should add root node.
{
if (root == null) (I think here is some problem)
{
root = new Node(newNode);
root.data = newNode;
root.left = null;
root.right = null;
return root;
}
if (newNode < root.data)
{
root.left = insertNode(root.left, newNode);
root = balance(root);
}
else if (newNode >= root.data)
{
root.right = insertNode(root.right, newNode);
root = balance(root);
}
return root;
}
}
Presentataion layer file
public partial class PresentationLayer : Form
{
BinaryTree obj = new BinaryTree();
int a, b;
public PresentationLayer()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) //add node button
{
int num = 0;
bool result = int.TryParse(textBox1.Text, out num);
if (result)
{
a = Int32.Parse(textBox1.Text);
obj.addNode(a); //It creates root
textBox1.Hide();
button1.Hide();
}
}
private void button2_Click_1(object sender, EventArgs e) //insert button
{
int num = 0;
bool result = int.TryParse(textBox2.Text, out num);
if (result)
{
b = Int32.Parse(textBox2.Text);
Node abc = new Node(b);
obj.insertNode(obj.root, b); //It is not creating root
textBox2.Clear();
}
}
}
}
Any help would be greatly appreciated!
You should add cases into the ll_rotation and rr_rotation functions to handle when the root is rotated. You should be able to check if the parameter parent is the same node as root, and if so, set root to refer to the new rotated node.
For example, per Wikipedia's example of left rotation:
P
/ \
/ \
A Q
/ \
B C
Rotates Left to become:
Q
/ \
/ \
P C
/ \
A B
If ll_rotation(P) is called where P is the same node as root, then the function should assign Q to be the new root
I came across some threads on StackOverflow but none of them quite cleared my doubts.
So the problem is simple. I need to iteratively insert elements into a binary tree. And this is my code.
BST newNode(int x)
{
BSTNodePtr node = (BSTNodePtr) malloc(sizeof(struct TreeNode));
node->Element = x;
node->Left = NULL;
node->Right = NULL;
return node;
}
BST Insert(int x, BST T)
{
BST temp_node = T;
while( T != NULL) {
if (x < T->Element)
T = T->Left;
else if (x >= T->Element)
T = T->Right;
}
T = newNode(x);
return temp_node;
}
However, when I'm finding the height of this tree I am always getting 0. The height code is
int Height(BST T)
{
if (T == NULL)
return 0;
return 1+(max(Height(T->Left), Height(T->Right)));
}
and this works perfectly fine when I do insertion recursively (using a function with the exact same signature)
What am I missing?
Here:
BST Insert(int x, BST T)
{
BST temp_node = T;
while( T != NULL) {
if (x < T->Element)
T = T->Left;
else if (x >= T->Element)
T = T->Right;
}
T = newNode(x);
return temp_node;
}
You navigate the tree until you hit T == NULL. Then you create a node and assign the pointer to it to T. Then you return the original value of T. You don't modify your tree at all. No node in it is made to point to the newly created node. T is just a local variable.
Couldn't solve the problem that way. This code, however, seems to work.
BST Insert(int x, BST T)
{
BST temp=T;
BST node=(BST)malloc(sizeof(struct TreeNode));
node->Element=x;
node->Left=NULL;
node->Right=NULL;
if (T==NULL)
{
T=node;
return(T);
//printf("%d\n",T->Element);
}
else
{
while(1)
{
if (temp->Element>=node->Element && temp->Left==NULL)
{
temp->Left=node;
break;
}
else if (temp->Element>=node->Element && temp->Left!=NULL)
{
temp=temp->Left;
}
else if (temp->Element<node->Element && temp->Right==NULL)
{
temp->Right=node;
break;
}
else
{
temp=temp->Right;
}
}
return(T);
}
}
Here's My implementation of the aforementioned problem:
bst* newNode(int x)
{
bst* T = new bst;
T->value = x;
T->left_child = T->right_child = NULL;
return T;
}
bst* bst_insert_iter(bst* T,int val)
{
if (T == NULL)
T = newNode(val);
else
{
bst *temp_node = T;
bool flag = true;
while(flag)
{
if (val <= temp_node->value)
{
if (temp_node->left_child == NULL)
{
temp_node->left_child=newNode(val);
flag = false;
}
else
temp_node = temp_node->left_child;
}
else
{
if (temp_node->right_child == NULL)
{
temp_node->right_child=newNode(val);
flag = false;
}
else
temp_node = temp_node->right_child;
}
}
}
return T;
}
You have the bug in your insert function. As I may assume, initially your tree is empty. so the first time you insert a node, the second argument is NULL, right? Then this function always returns NULL to you as you always pass a NULL value.
template <class T>
class TreeNode{
private:
T data;
TreeNode<T>* right,*left;
public:
void setData(T d){
this->data =d;
}
T getData(){
return this->data;
}
void setRight(TreeNode<T>* r){
this->right =r;
}
TreeNode<T>* getRight(){
return this->right;
}
void setLeft(TreeNode<T>* r){
this->left =r;
}
TreeNode<T>* getLeft(){
return this->left;
}
static TreeNode<T>* newNode(T data){
TreeNode<T>* n = new TreeNode<T>();
n->setData(data);
n->setRight(NULL);
n->setLeft(NULL);
return n;
}
};
template <class T>
class BinaryTree{
private:
TreeNode<T>* root;
public:
void insert(T data){
TreeNode<T>* n = TreeNode<T>::newNode(data);
if(root==NULL)
root = n;
else{
TreeNode<T>* t = root;
while(t!=NULL){
if(n->getData() >= t->getData()){
if(t->getRight()==NULL){
t->setRight(n); //newnode attached as right child in tree
t = NULL;
}
else
t = t->getRight();
}
else{
if(t->getLeft()==NULL){
t->setLeft(n); //newnode attached as left child in tree
t=NULL;
}
else
t = t->getLeft();
}
}
}
}
void preorder(){
TreeNode<T>* t = root;
preorderUtil(t);
}
void preorderUtil(TreeNode<T>* node){
if(node==NULL)
return;
preorderUtil(node->getLeft());
cout<<node->getData()<<" ";
preorderUtil(node->getRight());
}
};
Your changes are not reflected in the tree. I followed this way to insert data iteratively and it works fine. The point is making a node inside your binarytree to point the newly created node such that it gets attached to the tree.
Here is my version , it seems to be working.
struct tree{
tree *left;
tree *right;
int key;
};
void insertBst(int k,tree *t)
{
tree *newK = new tree[sizeof(tree)];
newK->key = k;
newK->left = NULL;
newK->right = NULL;
if((t)->key == NULL)
{
t=newK;
return;
}
else{
bool found = false;
tree *root = t;
tree *parent = NULL;
while(root != NULL)
{
parent = root;
if(root->key < newK->key)
{
root=root->right;
}
else if(root->key > newK->key)
{
root=root->left;
}
else{
//Here we have duplicates!! so do nothing
root = root;
}
}
if(parent->key > newK->key) parent->left = newK;
else parent->right = newK;
}
}