I have this code
tree match {
case EmptyNode =>
//do stuff with empty node
case Node(left, right, value) =>
//do stuff with node contents
}
However what if I want to update the value of a node? I tried doing value = newValue inside the case, but it doesn't seem to be allowed.
Structure of my trees/nodes:
sealed trait Tree
case class Node(var left: Tree, var right: Tree, var value: String) extends Tree
case object EmptyNode extends Tree
You can reference the actual node with # notation:
case n#Node(left, right, value) => n.value = "newValue"
Noah's answer does show the way to change the value of the node, but you shouldn't do that. One of the main ideas of scala is to promote immutable data structures, i.e. once you define an object, you don't change it.
This is particularly important in a tree, because by changing the value of the node, you are potentially making your tree inconsistent (values to the left of the node may no longer be smaller). Instead, always keep nodes values immutable and add or delete nodes as needed, minding rebalancing of the tree when a node is deleted.
Related
type struct Node {
x Data
l *Node
r *Node
}
Given the struct above, I am working on various implementations of binary search trees, all within the same package so that they can share internals without a public interface. However, some trees require a rank field as part of their node, which I would like to create as an extension of the base struct. I do not want the trees that do not require a rank field to allocate a node with a rank field.
type struct RankedNode {
Node
z rank
}
At first, this seems correct and communicates clear intent to me. However, this does not work because the internal l and r fields are of type Node, breaking code like this:
func (p *RankedNode) heapify() *RankedNode {
// ...
p.l.heapify()
p.r.heapify()
}
Of course, p.l and p.r are of type Node, so heapify is not defined. We can make the assumption that any node can only be linked to nodes of the exact same type.
Q: Is a Node interface and type assertions the only way to achieve this without generics?
func (p *RankedNode) heapify() *RankedNode {
// ...
p.L().(*RankedNode).heapify()
p.R().(*RankedNode).heapify() // :(
}
How I make an insert method in java for a tree which only need a value i.e insert(int value)
Yes it could be a tree.
In C++ for example, the tree would be a class, and then you would do mytree.insert(5);, which would insert 5 to an instance of a class that represents your data structure.
I was trying for this problem but not able to crack it. We have a Binary Tree and I want delete a given node from the tree but we don't have reference of root node. I am getting an idea how can we do this without having reference of root node. We do have the reference to node5, like in the image.
Update considering the new edit.
Since this is NOT a Binary Search Tree, in this case I'm assuming the node order in the tree is not relevant and the tree will not have duplicates, so removing node5 will be possible with the same data structure we defined above, but we need to include a parent node reference (for step 3 detailed below):
node {
d: data
leftChild: node
rightChild: node
parent: node
}
Now we can remove node5 modifying the tree without accessing/modifying the root (node1).
You'll have to do the following:
(Remember that node 5 is also a Binary subtree, so after
modifying it, we want the whole Binary Tree to still remain one!)
Find node5's deepest node. You need to traverse node5's node reference as a tree.
(*Be careful with how you pass the arguments. root should be a copy,
so that it doesn't mess with node5' as a root, but level and
deepestNode should be references.)
findDeepestNode(root: node, level: integer, deepestNode: node) {
if (root != null) {
level = level + 1
find(root.left, level)
if (level > deepestlevel) {
deepestNode = root; // node reference to the deepestNode
deepestlevel = level;
}
find(root.right, level);
}
}
Once executing this, deepestNode in your case will be node7 or node8. It doesn't matter.
Now make node5's value equal to deepestNode's value. In our pseudocode:
node5.data = deepestNode.data // Replacing node5's value with the deletingNode's one.
The tree now has a duplicate value. You still have deepestNode. So now you assign deepestNode parent's reference to null and delete
deepestNode as a reference. This step is the reason we need to include a parent node reference.
Your removal is complete!
Given nothing else but the tree itself, then you'll always have to search for the node you want to remove before removing it. If you can set yourself up for success by keeping pointers to the nodes you may want to remove beforehand, then the answer could be yes!
I am trying to use the Linked List Class implementation in MATLAB.
Now, it says the only way to insert a node into the list is by using insertBefore() or insertAfter().
But I want to insert the node manually, by specifying the Next value of the new node, like
newnode = dlnode(new);
ptr.Next = newnode;
newnode.Next=ptrnxt;
Would this work? I cannot use the insertBefore() or insertAfter() in my particular application since I am not maintaining a pointer of the current node.
Details regarding the linked list class is given here.
No, I don't think that would work with just those three lines of code because it ignores all the other logic that occurs to make sure that the Next and Prev are set for newnode and ignores the update to ptrnxt that would need to occur so that its Prev is now newnode. (And the Next property is private so you would have to change that to public…)
It is unclear by what you mean with I cannot use the insertBefore() or insertAfter() in my particular application since I am not maintaining a pointer of the current node. Yet you have the nodes that you want to insert newnode between? I'm guessing that the order of your nodes (prior to the insertion of the new one) is …,ptr,ptrnxt,…. Then why not just use
newnode.insertAfter(ptr);
which would change the order to …,ptr,newnode,ptrnxt,… and all three properties for each node would be set correctly/automatically.
Else, you would have to change your code to something like
newnode = dlnode(new);
ptr.Next = newnode;
newnode.Prev = ptr; % to make sure that newnode points back to ptr
newnode.Next = ptrnxt;
ptrnxt.Prev = newnode; % to make sure that ptrnxt points back to newnode
Much easier and safer to use the insertAfter and insertBefore methods.
I have a RadTreeView C# component. The tree is nested, so some Nodes have their sub-trees, stored in Nodes property of upper-level Nodes.
Now I need to find a node by value. Node is hidden somewhere in subtrees. If I use call
RadTreeNode rtn= PagesTreeView.Nodes.FindNodeByValue(i.ToString());
where PagesTreeView is my tree, then it searches only across top-level nodes.
How I can Find Node by Value using not only Nodes from the current level of tree, but also dive into subtrees? Do I need to write such recursive search myself or there is a straightforward solution?
Recursively searching the RadComboBox
There isn't a built in function to recursively search, however you can roll your own pretty easiliy. This should work for you (not tested):
RadTreeNode FindNodeRecursive(RadTreeNodeCollection nodes, string value)
{
foreach (RadTreeNode node in nodes)
{
if(node.Value == value)
return node;
if (node.Nodes.Count > 0)
{
FindNodeRecursive(node.Nodes, value);
}
return null;
}
}
And then call it like this:
var node = FindNodeRecursive(PagesTreeView.Nodes, i.ToString());
Yes, you would need to write your own recursive function to do the search. Another option if you are using the ASP.NET AJAX version of the control is the GetAllNodes() method. It returns all nodes in the tree hierarchy (I'm guessing it uses recursion under the hood). Once you have the entire list you would search it for the node you care about. The big drawback with that approach is if you have a lot of nodes the search could be slow and consume a lot of memory. Doing your own recursive search is the best approach.
See this article for more info.
Old question but I faced this same problem in my application, how to search through the hierarchical tree nodes.
I would like to share one correction to previous solutions proposal. When calling FindNodeRecursive() recursively the return value of your recursive call is never being evaluated or assigned to a variable. So, you will always end up with going through the foreach loop and return value is null.
Corrected and tested function code (WPF C#):
RadTreeNode FindNodeRecursive(RadTreeNodeCollection nodes, string value)
{
RadTreeNode ret = null;
foreach (RadTreeNode node in nodes)
{
if(node.Value == value)
return node;
if (node.Nodes.Count > 0)
{
ret = FindNodeRecursive(node.Nodes, value);
}
return ret;
}
}
Function use:
var node = FindNodeRecursive(PagesTreeView.Nodes, i.ToString());
if (node != null) // found
{
;
}