Please share me your thoughts and any solution to this problem of copying the full non-binary tree, and it may include loops as well in which some of the children are connected to other parent nodes.
Example:
Here, "A" is the root or parent, and its children are "B" and "C" as usual, and at the end, child "G" is connected back to its grand-parent level "B", and similarly the "I" is connected to its immediate parent "C", so these are like a loops, and this also needs to be copied in the new tree as is. So, here we need additional logic to identify the loops while copying the children nodes, and not getting into an infinite loop, and eventually return the copy of the whole tree.
A
- B
- D
- E
- F
- G --> B
- C
- I --> C
- K
This class or node structure can be like this:
public class Node{
private String value;
private List<Node> childrens;
public Node copyTree(Node root) {
...
//return
}
}
Thanks for our help.
I think the most direct way of doing this is to keep a map from nodes that have been copied to their copies. Then just check against the map before making a new copy of a node. Something like this (untested) should work:
public static Node copyTree(Node root) {
return copyTree(root, new HashMap<>());
}
private static Node copyTree(Node root, Map<Node, Node> images) {
Node copy = images.get(root);
if (copy == null) {
copy = new Node();
// register the copy before recursing on children
images.put(root, copy);
// now fill in the copy
copy.value = root.value;
copy.children = new ArrayList<>();
for (Node child : root.children) {
copy.children.add(copyTree(child, images);
}
}
return copy;
}
Related
//Deletes data given from the linked list
public void deleteByValue(T data) {
//if empty then simply return
if (isEmpty())
return;
//Start from head node
Node currentNode = this.headNode;
Node prevNode = null; //previous node starts from null
if(currentNode.data.equals(data)) {
//data is at head so delete from head
deleteAtHead();
return;
}
//traverse the list searching for the data to delete
while (currentNode != null) {
//node to delete is found
if (data.equals(currentNode.data)){
prevNode.nextNode = currentNode.nextNode;
return;
}
prevNode = currentNode;
currentNode = currentNode.nextNode;
}
}
}
Hi all, I am quite new to data structure and I am confused when I learned how to delete one specific value in the single linked list.
So when we traverse the LinkedList, we have a line like this
prevNode.nextNode = currentNode.nextNode;
I think this already means that we have connected "the previous node before the target node" and "the next node before the current node". Why do we still have these two lines after the traversing of the linked list?
prevNode = currentNode;
currentNode = currentNode.nextNode;
Are these two lines mean we are connecting the original previous node with the original next node? I always got lost when the code referred to the "currentNode".How can we tell which is the current "currentNode"?
Could someone help me with this? Visualized answer is appreciated. Thanks so much!
Why do we still have these two lines after the traversing of the linked list?
These are not after traversing; these are the traversing itself.
Some things to note:
An assignment to an attribute will mutate the list, like prevNode.nextNode = currentNode.nextNode does.
An assignment to a variable will not mutate the list, but can make a reference to a different node, like currentNode = currentNode.nextNode does. This really is the core of traversing: it makes the variable currentNode hop from one node to the next -- without changing anything to the list it is traversing.
In this specific algorithm, when the mutation with prevNode.nextNode = currentNode.nextNode is performed, the next thing that happens is a return -- so there is no further traversal happening.
I'm still new to coding and I'm trying to learn how to create a linked list. What does this part mean? I can't seem to visualize this in my head.
static class Node {
int data;
Node next;
Node(int d){
data = d;
next = null;}
}
So this is a simple visual of a linked list. Your code represents a node class, so thats just the framework for a node. But you can think of that code representing one node, so it could represent the fourth node in this diagram. Thus, its data value would be {D} and its next value would be null.
In a linked list, the next node object it represented by the next variable. So if the node you are looking at is the second node, then your next variable will be the third node.
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 want to design a map like in traveling salesman problem.
There are a number of nodes, some connected to another.
One node can be connected to many other nodes.
I have designed some, which one is better ? Or maybe there are another better design ?
1.)
class Node {
private int ID;
private int position-x;
private int position-y;
}
class Connection {
private int ID;
private Node first;
private Node second;
public void ConnectTwoNodes( Node a, Node b ) { ... }
}
2.)
class Node {
private int ID;
private int position-x;
private int position-y;
private ArrayList<Node> anotherNodes; // array of connected nodes
public void ConnectTo( Node another ) { ... }
}
Your language seems to be C++.
Your solution 1. has the following problems:
class Connection seems to "aggregate" the Nodes. It should rather be an association in OOspeak (a pointer to a Node to make it understandable to mere mortals)
a Connection object has absolutely no reason to exist, unless it connects 2 Nodes. So the function of ConnectTwoNodes belongs in a constructor. In other words rename it to Connection.
In your second solution it also seems that a Node contains the other Nodes. But in reality they exist independently. Again, you need associations, or pointers to other Nodes.
I actually prefer the 1. approach. Or a non-OO solution with a matrix, with "from" Nodes on one axle and "to" Nodes on the other. It also allows you to handle cases when it's possible to get from New York to Paris, Texas but not vice versa, because there are no more flights in the afternoon. In other words a directional graph.
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
{
;
}