I have a VirtualStringTree with X roots and X childnodes.
Every root has a special NodeData assigned.
Every childnode has another NodeData assigned.
How do I know OnFreeNode which is which? Cause I can't free the data without knowing which record is assigned to it.
Any Ideas?
To determine a node level use the GetNodeLevel function. It returns the 0 based level index, where 0 means a root node, 1 is for a root's child, 2 is for a root's grandchild etc.
So, in OnFreeNode event you can use something like this:
procedure TForm1.VirtualTreeFreeNode(Sender: TBaseVirtualTree;
Node: PVirtualNode);
begin
case VirtualTree.GetNodeLevel(Node) of
0: // free your root node data
1: // free your root's child node data
end;
end;
Related
I need to implement a simple (but not binary) tree in Julia. Basically, each node needs to have an integer ID, and I need a convenient way to get a list of children for a node + add child to an existing node by ID.
e.g. 0->1->(2->(3,4,5),6)
where each number represents a node, I need the functions children(2) and add(7 as child of 4).
I am aware that similar tree implementations can be found for other languages, but I am pretty new to OOP/classes/data structures and not managing to "translate" them to Julia.
You didn't state whether you want the IDs to be assigned automatically as new nodes are added, or if you want to specify them when you add the children (which would involve some form of more complicated lookup).
If the IDs can be assigned, you could implement a tree structure as follows:
type TreeNode
parent::Int
children::Vector{Int}
end
type Tree
nodes::Vector{TreeNode}
end
Tree() = Tree([TreeNode(0, Vector{Int}())])
function addchild(tree::Tree, id::Int)
1 <= id <= length(tree.nodes) || throw(BoundsError(tree, id))
push!(tree.nodes, TreeNode(id, Vector{}()))
child = length(tree.nodes)
push!(tree.nodes[id].children, child)
child
end
children(tree, id) = tree.nodes[id].children
parent(tree,id) = tree.nodes[id].parent
Otherwise, you might want to use Dict{Int,TreeNode} to store the tree nodes.
Is there is some algorithm to reach the grandchildren of a binary tree? Like the example?
In the picture, there are nodes linking grandparents to their grandchildren, whereas a normal binary tree only links children to parents. What algorithm would one use to link to grandparents?
EDIT:
each node has an index and two values.
[index]
[value value];
What im trying to do:
index[3] and index[4] = value[0];
index[5] and index[6] = value[1];
index[7] and index[8] = value[2];
index[9] and index[10] = value[3];
.... ETC
Typically you construct each node in a binary tree with two pointers: a left child pointer 'node.left' and a right child pointer node 'node.right'. Then the four grandchildren of a node could be located with the expressions 'node.left.left', 'node.left.right', 'node.right.left', and 'node.right.right'. These expressions will evaluate very quickly.
Accessing the grandchildren via this technique will make everything much simpler for the person who has to maintain your code, which might even be you ten months from now after you have had time to forget that you ever had this discussion.
If you insist on storing the grandchild pointers redundantly then you will need four additional pointers per node: 'node.leftleft', 'node.leftright', 'node.rightleft', and 'node.rightright'.
This feels like the very definition a bad idea. Not only will the tree be big and clumsy, but every time you add or delete a node you will find yourself updating a metric barrowload of pointers. In order to recoup the time you will spend debugging such a mess, you will have to use the program for about nine thousand years.
0
/ \
1 2
/ \ / \
3 4 5 6
[0,1,2,3,4,5,6] Binary Tree as Array
left = 2n+1
right = 2n+2
left-left-grandChild = 2(2n+1)+1 => 4n+3
left-right-grandChild = 2(2n+1)+2 => 4n+4
right-left-grandChild = 2(2n+2)+1 => 4n+5
right-right-grandChild = 2(2n+2)+2 => 4n+6
I have homeowork to write pseudo code to check if a valid binary tree is a search binary tree.
I created an array to hold the in-order values of the tree. if the in-order values are in decreasing order it means it is indeed BST. However I've got some problem with the recursion in the method InOverArr.
I need to update the index of the array in order to submit the values to the array in the order they are at the tree.
I'm not sure the index is really updated properly during the recursion.. is it or not? and if you see some problem can you help me fix this? thanks a lot
pseudo code
first function
IsBST(node)
size ← TreeSize(node)
create new array TreeArr of Size number of cells
index ← 0
few comments:
now we use the IN_ORDER procedure with a small variation , I called the new version of the procedure: InOrderArr
the pseudo code of InOrderArr is described below IsBST
InOrderArr(node, TreeArr, index)
for i from 1 to size-1 do
if not (TreeArr[i] > TreeArr[i-1]) return
false
return true
second function
InOrderArr (node, Array, index)
if node = NULL then return
else
InOrderArr (node.left, Array, index)
treeArr[index] = node.key
index ← index + 1
InOrderArr (node.right, Array, index)
Return
Your code is generally correct. Just three notes.
The correctness of the code depends on the implementation, specifically on the way of index handling. Many programming languages pass arguments to subroutines by value. That means the subroutine receives a copy of the value and modifications made to the parameter have no effect on the original value. So incrementing index during execution of InOrderArr (node.left, Array, index) would not affect the position used by treeArr[index] = node.key. As a result only the rightmost path would be stored in the array.
To avoid that you'll have to ensure that index is passed by reference, so that incrementation done by a callee advances the position used later by a caller.
BST is usually defined so that the left subtreee of a node contains keys that are less than that node's key, and the right subtree contains nodes with greater keys – see Wikipedia's article on BST. Then the inorder traversal retrieves keys in ascending order. Why do you expect descending order?
Possibly it would be more efficient to drop the array and just recursively test a definition condition of BST?
Whenever we follow a left link we expect keys which are less than the current one. Whenever we follow the right link we expect keys greater the the current one. So for most subtrees there is some interval of keys values, defined by some ancestor nodes' keys. Just track those keys and test whether the key falls inside the current valid interval. Be sure to handle 'no left end defined' condition on the letfmost path and 'no right end' on the rightmost path of the tree. At the root node there's no ancestor yet, so the root key is not tested at all (any value is OK).
EDIT
C code draft:
// Test a node against its closest left-side and right-side ancestors
boolean isNodeBST(NODE *lt, NODE *node, NODE *rt)
{
if(node == NULL)
return true;
if(lt != NULL && node->key < lt->key)
return false;
if(rt != NULL && node->key > rt->key)
return false;
return
isNodeBST(lt, node->left, node) &&
isNodeBST(node, node->right, rt);
}
boolean isTreeBST(TREE *tree)
{
return isNodeBST( NULL, tree->root, NULL);
}
Suppose that I have a tree to traverse using a Depth First Search, and that my algorithm for traversing it looks something like this:
algorithm search(NODE):
doSomethingWith(NODE)
for each node CHILD connected to NODE:
search(CHILD)
Now in many languages there is a maximum depth to recursion, for example if the depth of recursion is over a certain limit, then the procedure will crash with a stack overflow.
How can this function be implemented without the recursion, and instead with a stack? In many cases, there are a lot of local variables; where can they be stored?
You change this to use a stack like so:
algorithm search(NODE):
createStack()
addNodeToStack(NODE)
while(stackHasElements)
NODE = popNodeFromStack()
doSomethingWith(NODE)
for each node CHILD connected to NODE:
addNodeToStack(CHILD)
As for your second question:
In many cases, there are a lot of local variables; where can they be stored?
These really can be kept in the same location as they were originally. If the variables are local to the "doSomethingWith" method, just move them into that, and refactor that into a separate method. The method doesn't need to handle the traversal, only the processing, and can have it's own local variables this way that work in its scope only.
For a slightly different traversal.
push(root)
while not empty:
node = pop
doSomethingWith node
for each node CHILD connected to NODE:
push(CHILD)
For an identical traversal push the nodes in reverse order.
If you are blowing your stack, this probably won't help, as you'll blow your heap instead
You can avoid pushing all the children if you have a nextChild function
Essentially you new up your own stack: char a[] = new char[1024]; or for type-safety, node* in_process[] = new node*[1024]; and put your intermediate values on this:
node** current = &in_process[0];
node* root = getRoot();
recurse( root, ¤t) ;**
void recurse( node* root, node** current ) ;
*(*current)++ = root; add a node
for( child in root ) {
recurse( child, current );
}
--*current; // decrement pointer, popping stack;
}
I have the following pseudo-code in my book for a breadth-first search:
function breadth_first_search:
begin
open := [Start]
closed := [];
while open != [] do
begin
remove leftmost state from open, call it X;
if X is a goal then return SUCCESS
else begin
generate children of X;
put X on closed;
discard children of X if already on open or closed;
put remaining children on right end of open;
end
end
return FAIL;
end
I've implemented a similar algorithm myself following these pseudo-code instructions. My question is, what is the simplest way to modify it so it maintains the solution path?
Simply knowing I can reach a solution isn't nearly as useful as having a list of transitions to get to the solution.
Set Parent[childNode] = currentNode as you enqueue each node (when you set Visible[Node] = 1).
Then recursively look up the Parent array, starting at the node you want and append each node you see in the Parent array to the path. Parent[root] is nil and the recursion will stop there.
Is there any possibility for you to change the Tree structure? If so, you might want to add a parent pointer in each node/leaf so when you find the solution you go up following parent pointers up to the root.