I have implemented a method to do a preorder traversal of a tree, which is not a binary tree. Every parent node of this tree has an array of children, so this is the method I am using:
void preorderTraversal(TreeNode tree)
{
if (tree == null)
return;
System.out.print(tree.element + " ");
for(TreeNode child : tree.childern) // children is an Arraylist
{
preorderTraversal(child);
}
}
Sample of linking children nodes to parent "tnAA"
/* Creating Object of class tree*/
Tree tree = new Tree();
tree.setRoot(tnAA);
TreeNode root2 = tree.getRoot();
/* creating the links between nodes of Tree*/
ArrayList<TreeNode> AA_children = new ArrayList<TreeNode>();
AA_children.add(tnBB);
AA_children.add(tnCC);
AA_children.add(tnDD);
tnBB.parent=tnAA; tnCC.parent = tnAA; tnDD.parent = tnAA;
// Tree
// A
// / | \
// B C D
// /\ |
// E F G
But it only outputs the root node, what's wrong with this method?
Solution: linking children array to each parent: tnAA.setChildern(AA_childern);
You never add anything to any node's childern list. You create an ArrayList called AA_childern, but it is not connected to the tree, and the tree doesn't know or care that it exists. Those child nodes need to be added to tnAA.childern.
P.S. The correct spelling is 'children'.
Related
The problem statement is:
Given a Binary Tree, convert this binary tree to a Doubly Linked List.
A Binary Tree (BT) is a data structure in which each node has at most two children.
A Doubly Linked List contains a previous pointer, along with the next pointer and data.
The order of nodes in Doubly Linked List must be the same as Inorder of the given Binary Tree.
The doubly linked list should be returned by taking the next pointer as right and the previous pointer as left.
You need to return the head of the Doubly Linked List.
For example:
4
/ \
2 5
/ \
1 3
The doubly linked list would be: 1 2 3 4 5
My code is:
class BinaryTreeNode
{
public :
T data;
BinaryTreeNode<T> *left;
BinaryTreeNode<T> *right;
BinaryTreeNode(T data) {
this -> data = data;
left = NULL;
right = NULL;
}
};
void inorder(BinaryTreeNode<int>* root,BinaryTreeNode<int>* &prev,BinaryTreeNode<int>* &nroot){
if(!root) return;
inorder(root->left,prev,nroot);
if(prev == NULL) nroot=root;
else{
root->left = prev;
prev->right=root;
}
prev=root;
inorder(root->right,prev,nroot);
}
BinaryTreeNode<int>* BTtoDLL(BinaryTreeNode<int>* root) {
BinaryTreeNode<int>* prev=NULL;
BinaryTreeNode<int>* nroot=NULL;
inorder(root,prev,nroot);
return nroot;
}
I have doubt regarding root.
The root pointer works with passing by value and does not works when it is passed by reference.
When root is passed by reference, it does not work.
void inorder(BinaryTreeNode<int>*& root,BinaryTreeNode<int>*& prev,BinaryTreeNode<int>* &nroot){
if(!root) return;
inorder(root->left,prev,nroot);
if(prev == NULL) nroot=root;
else{
root->left = prev;
prev->right=root;
}
prev=root;
inorder(root->right,prev,nroot);
}
How can I know which variable should be passed by reference and which variable should by passed by value with regard to pointers?
At first glance, one problem is the API of inorder itself. You are assigning nroot = root; to see why this is a problem, consider this simpler example:
void set_x(int *x, int *y)
{
x = y;
}
Remember that pointers are really just memory addresses. So, the assignment of x = y says, "replace the memory address that x contains, and set it to whatever y contains". At no stage do you actually change the value at the memory address.
Now, considering nroot = root again, here you are just giving the local variable you have a new memory address, but not updating anything. So at your call side BTtoDLL, you provide it nullptr for the address, to which it never uses it, and never sets it. So, BTtoDLL will never see any change to nroot.
(I'm not native speaker. I apologize for my poor English😿)
If there is a tree like below.
Each node is an object.
ex) nodeA.data = 23, nodeA.children = [nodeB, nodeC]
If we search this tree in DFS from the root, the result will be
23 - 19 - 15 - 22 - 35 - 31 - 38
and the code below is an implementation of DFS, which successfully logs the same result as above.
class TreeNode {
constructor(data) {
this.data = data;
this.children = [];
}
// ... omit
depthFirstTraversal() {
console.log(this.data);
this.children.forEach(child => child.depthFirstTraversal());
}
}
But I'm curious :
What if the recursive call inside the forEach loop is repeated and finally "child" parameter points to nodeD?
The situation you fear for will not happen.
The child variable in the forEach callback could only be undefined if in a children array you have undefined values. But that would be an odd thing to do. In reality, when this is a leaf node (like node D), it will have an empty this.children array, and so the forEach loop will not make any iterations, and its callback function will not be called.
That is where the base case of the recursion is realised: when this.children.length == 0.
I always get null value. I am beginner in this language. Thank you for understanding.
class Node{
int data;
Node next;
Node(int value){
data = value;
}
}
void addNode(Node headNode, int aValue){
Node newNode = new Node(aValue); //creating new node
newNode.next = headNode; // pointing the next to headNode
headNode = newNode; // updating the head Node
}
void main(){
Node head = Node(1);
addNode(head,2);
addNode(head,3);
print(head.next.data); //here I always get null
}
Your help will truely be appreciated.
Consider where you update the value of headNode. What exactly are you assigning to there?
headNode has function scope, which means it only exists within the addNote function. Similarly head in your main function also has function scope, so it is only accessible in your main function.
It seems like you are trying to update head from within addNode but that is not what you have here.
One possible solution would be to return the newly created node from addNode and use the returned value to reassign head in the main function. It would look something like this:
Node addNode(Node headNode, int aValue){
Node newNode = new Node(aValue);
newNode.next = headNode;
return newNode;
}
void main(){
Node head = Node(1);
head = addNode(head,2);
head = addNode(head,3);
print(head.next.data);
}
One more thing to think about: What does your list look like when execution reaches the end of your program? Is it [1] > [2] > [3] or [3] > [2] > [1] ?
Assume u have the following recursive record type
type Parent = {
Name : string
Age : int
Children : Child list }
and Child = {
Name : string
Parent : Parent option }
I can easily create instances with
module Builder =
let create name kids =
let rec makeChild kid = { kid with Parent = parent |> Some }
and parent =
{
Name = name
Age = 42
Children = children
}
and children = kids |> List.map makeChild
parent
let createChild name =
{ Child.Name = name; Parent = None }
But when i try to "transform" an existing adult into a parent using "with" like that:
module Builder2 =
let createAdult name age =
{ Parent.Name = name; Age = age; Children = [] }
let create name kids =
let rec makeChild kid = { kid with Parent = parent |> Some }
and parent =
{ (createAdult name 42) with
Children = children
}
and children = kids |> List.map makeChild
parent
let createChild name =
{ Child.Name = name; Parent = None }
I get:
error FS0040: This and other recursive references to the object(s) being defined will be checked for initialization-soundness at runtime through the use of a delayed reference. This is because you are defining one or more recursive objects, rather than recursive functions. This warning may be suppressed by using '#nowarn "40"' or '--nowarn:40'.
and "Children = children" in the "parent" definition is highlighted.
What am i doing wrong?
Edit:
One more point: when i move the "Builder" (which worked) into a different assembly (e.g. the test assembly) it immediately stops working with:
error FS0261: Recursive values cannot be directly assigned to the non-mutable field 'Children' of the type 'Parent' within a recursive binding. Consider using a mutable field instead.
Edit:
Based on the comments I tried
let create name kids =
let rec makeChild kid = { kid with Parent = parent |> Some }
and adult = createAdult name 42
and parent =
{ adult with Children = children }
and children = kids |> List.map makeChild
but still no luck - the compiler still does not see this usecase similar to the working one :(
First of all, the message you posted in your question is just a warning - it tells you that you can only initialize a recursive value if the construction does not evaluate the entire value immediately (this cannot be done when the first value depends on the second and vice versa).
You can sometimes just ignore the warning, but in your case, the values are actually mutually dependent, so the following gives an error:
Builder2.create "A" [Builder2.createChild "B"]
System.InvalidOperationException: ValueFactory attempted to access the Value property of this instance.
One way to introduce some form of delay is to change the parent to include children as a lazy sequence seq<'T> rather than a fully evaluated list list<'T>:
type Parent = {
Name : string
Age : int
Children : Child seq }
and Child = {
Name : string
Parent : Parent option }
Then you also need to change Builder2 to use Seq.map (to keep things lazy):
let create name kids =
let rec makeChild kid = { kid with Parent = parent |> Some }
and parent =
{ (createAdult name 42) with
Children = children
}
and children = kids |> Seq.map makeChild
Now you still get the warning (which you can turn off), but the following works and creates a recursive value:
let p = Builder2.create "A" [Builder2.createChild "B"]
As an aside, I think it is probably better to avoid recursive values - I suspect that one way reference (parent referencing children, but not the other way round) would let you do what you need - and your code would likely be simpler.
cartermp found and posted the solution here:
https://github.com/Microsoft/visualfsharp/issues/4201
I published a repro here
https://github.com/plainionist/DevNull/tree/master/src/FSharpCopyRecordRecursive
and of course the proposed solution works like a charm
I have a tree like structure of text nodes that might have another text nodes as children, and I need to update one value in it. What's the easiest way to update text node that's somewhere deep in that tree (or it is not in that tree at all)?
In a non-immutable language, I would simply change a value of that item, and that's it, but it's quite tricky in an immutable language like Elm.
type alias Item =
{ id: String
, text: String
, children: ChildItems
}
type ChildItems = ChildItems (List Item)
type alias Model =
{ rootItem: Item
}
updateItem: Item -> Item -> Item
updateItem: rootItem item =
-- TODO
...
update model =
case msg of
UpdateItem item updatedText ->
let
updatedItem = { item | text = updatedText }
in
({ model | rootItem = (updateItem model.rootItem updatedItem) }, Cmd.none)
this is what I came up with
updateItem: Item.Item -> Item.Item -> Item.Item
updateItem rootItem updatedItem =
if rootItem.id == updatedItem.id then
updatedItem
else
case rootItem.children of
Item.ChildItem [] ->
rootItem
Item.ChildItem children ->
let
updatedChildren =
case children of
[] ->
[]
children ->
List.map (\item ->
updateItem rootItem item) children
in
{ rootItem | children = Item.ChildItem updatedChildren }
but I'm getting an Maximum call stack size exceeded error
The reason you're getting the stack overflow is because you are returning rootItem instead of [] in the Item.ChildItems [] case.
I'm going to modify your code a bit because there are some common patterns we can pull out. First off, let's take the underlying tree-ish structure and make that more generic so that it could fit any type of thing, not just Item:
type Node a
= Node a (List (Node a))
That gives us a structure that always has a root node and may have any number of children, each of who may also have any number of children.
If we think about the algorithm you were going for, we can extrapolate a familiar pattern. You have a structure with multiple items and you want an algorithm that visits each item and optionally changes it. That sounds a lot like List.map. It's such a common idiom that it's a good idea to call our generalized function map:
map : (a -> b) -> Node a -> Node b
map f (Node item children) =
Node (f item) (List.map (map f) children)
(Side note: We've just stumbled into functors!)
Since I've taken the idea of children and placed it into the Node type, we need to modify the alias Item like so:
type alias Item =
{ id: String
, text: String
}
Now that we have an Item, it will be helpful to have a function that can update it if the id matches a certain value. Since in the future, you may have more update functions you want to perform, it's best to keep the lookup and ID matching portion separate from the function you actually want to perform:
updateByID : String -> (Item -> Item) -> Item -> Item
updateByID id f item =
if item.id == id then
f item
else
item
Now to perform an update on an item matching the id, anywhere within the tree, you can simply do this:
map (updateByID "someID" (\x -> { x | text = "Woohoo!" })) rootNode